LearnOpenGL

Translation in progress of learnopengl.com.
git clone https://git.mtkn.jp/LearnOpenGL
Log | Files | Refs

Advanced-GLSL.html (48266B)


      1 <!DOCTYPE html>
      2 <html lang="ja"> 
      3 <head>
      4     <meta charset="utf-8"/>
      5     <title>LearnOpenGL</title>
      6     <link rel="shortcut icon" type="image/ico" href="/favicon.ico"  />
      7 	<link rel="stylesheet" href="../static/style.css" />
      8 	<script id="MathJax-script" async src="https://cdn.jsdelivr.net/npm/mathjax@3/es5/tex-chtml.js"> </script>
      9 	<script src="/static/functions.js"></script>
     10 </head>
     11 <body>
     12 	<nav>
     13 <ol>
     14 	<li id="Introduction">
     15 		<a href="https://learnopengl.com/Introduction">はじめに</a>
     16 	</li>
     17 	<li id="Getting-started">
     18 		<span class="closed">入門</span>
     19 		<ol>
     20 			<li id="Getting-started/OpenGL">
     21 				<a href="https://learnopengl.com/Getting-started/OpenGL">OpenGL </a>
     22 			</li>
     23 			<li id="Getting-started/Creating-a-window">
     24 				<a href="https://learnopengl.com/Getting-started/Creating-a-window">ウィンドウの作成</a>
     25 			</li>
     26 			<li id="Getting-started/Hello-Window">
     27 				<a href="https://learnopengl.com/Getting-started/Hello-Window">最初のウィンドウ</a>
     28 			</li>
     29 			<li id="Getting-started/Hello-Triangle">
     30 				<a href="https://learnopengl.com/Getting-started/Hello-Triangle">最初の三角形</a>
     31 			</li>
     32 			<li id="Getting-started/Shaders">
     33 				<a href="https://learnopengl.com/Getting-started/Shaders">シェーダー</a>
     34 			</li>
     35 			<li id="Getting-started/Textures">
     36 				<a href="https://learnopengl.com/Getting-started/Textures">テクスチャ</a>
     37 			</li>
     38 			<li id="Getting-started/Transformations">
     39 				<a href="https://learnopengl.com/Getting-started/Transformations">座標変換</a>
     40 			</li>
     41 			<li id="Getting-started/Coordinate-Systems">
     42 				<a href="https://learnopengl.com/Getting-started/Coordinate-Systems">座標系</a>
     43 			</li>
     44 			<li id="Getting-started/Camera">
     45 				<a href="https://learnopengl.com/Getting-started/Camera">カメラ</a>
     46 			</li>
     47 			<li id="Getting-started/Review">
     48 				<a href="https://learnopengl.com/Getting-started/Review">まとめ</a>
     49 			</li>
     50 		</ol>
     51 	</li>
     52 	<li id="Lighting">
     53 		<span class="closed">Lighting </span>
     54 		<ol>
     55 			<li id="Lighting/Colors">
     56 				<a href="https://learnopengl.com/Lighting/Colors">Colors </a>
     57 			</li>
     58 			<li id="Lighting/Basic-Lighting">
     59 				<a href="https://learnopengl.com/Lighting/Basic-Lighting">Basic Lighting </a>
     60 			</li>
     61 			<li id="Lighting/Materials">
     62 				<a href="https://learnopengl.com/Lighting/Materials">Materials </a>
     63 			</li>
     64 			<li id="Lighting/Lighting-maps">
     65 				<a href="https://learnopengl.com/Lighting/Lighting-maps">Lighting maps </a>
     66 			</li>
     67 			<li id="Lighting/Light-casters">
     68 				<a href="https://learnopengl.com/Lighting/Light-casters">Light casters </a>
     69 			</li>
     70 			<li id="Lighting/Multiple-lights">
     71 				<a href="https://learnopengl.com/Lighting/Multiple-lights">Multiple lights </a>
     72 			</li>
     73 			<li id="Lighting/Review">
     74 				<a href="https://learnopengl.com/Lighting/Review">Review </a>
     75 			</li>
     76 		</ol>
     77 	</li>
     78 	<li id="Model-Loading">
     79 		<span class="closed">Model Loading </span>
     80 		<ol>
     81 			<li id="Model-Loading/Assimp">
     82 				<a href="https://learnopengl.com/Model-Loading/Assimp">Assimp </a>
     83 			</li>
     84 			<li id="Model-Loading/Mesh">
     85 				<a href="https://learnopengl.com/Model-Loading/Mesh">Mesh </a>
     86 			</li>
     87 			<li id="Model-Loading/Model">
     88 				<a href="https://learnopengl.com/Model-Loading/Model">Model </a>
     89 			</li>
     90 		</ol>
     91 	</li>
     92 	<li id="Advanced-OpenGL">
     93 		<span class="closed">Advanced OpenGL </span>
     94 		<ol>
     95 			<li id="Advanced-OpenGL/Depth-testing">
     96 				<a href="https://learnopengl.com/Advanced-OpenGL/Depth-testing">Depth testing </a>
     97 			</li>
     98 			<li id="Advanced-OpenGL/Stencil-testing">
     99 				<a href="https://learnopengl.com/Advanced-OpenGL/Stencil-testing">Stencil testing </a>
    100 			</li>
    101 			<li id="Advanced-OpenGL/Blending">
    102 				<a href="https://learnopengl.com/Advanced-OpenGL/Blending">Blending </a>
    103 			</li>
    104 			<li id="Advanced-OpenGL/Face-culling">
    105 				<a href="https://learnopengl.cm/Advanced-OpenGL/Face-culling">Face culling </a>
    106 			</li>
    107 			<li id="Advanced-OpenGL/Framebuffers">
    108 				<a href="https://learnopengl.com/Advanced-OpenGL/Framebuffers">Framebuffers </a>
    109 			</li>
    110 			<li id="Advanced-OpenGL/Cubemaps">
    111 				<a href="https://learnopengl.com/Advanced-OpenGL/Cubemaps">Cubemaps </a>
    112 			</li>
    113 			<li id="Advanced-OpenGL/Advanced-Data">
    114 				<a href="https://learnopengl.com/Advanced-OpenGL/Advanced-Data">Advanced Data </a>
    115 			</li>
    116 			<li id="Advanced-OpenGL/Advanced-GLSL">
    117 				<a href="https://learnopengl.com/Advanced-OpenGL/Advanced-GLSL">Advanced GLSL </a>
    118 			</li>
    119 			<li id="Advanced-OpenGL/Geometry-Shader">
    120 				<a href="https://learnopengl.com/Advanced-OpenGL/Geometry-Shader">Geometry Shader </a>
    121 			</li>
    122 			<li id="Advanced-OpenGL/Instancing">
    123 				<a href="https://learnopengl.com/Advanced-OpenGL/Instancing">Instancing </a>
    124 			</li>
    125 			<li id="Advanced-OpenGL/Anti-Aliasing">
    126 				<a href="https://learnopengl.com/Advanced-OpenGL/Anti-Aliasing">Anti Aliasing </a>
    127 			</li>
    128 		</ol>
    129 	</li>
    130 	<li id="Advanced-Lighting">
    131 		<span class="closed">Advanced Lighting </span>
    132 		<ol>
    133 			<li id="Advanced-Lighting/Advanced-Lighting">
    134 				<a href="https://learnopengl.com/Advanced-Lighting/Advanced-Lighting">Advanced Lighting </a>
    135 			</li>
    136 			<li id="Advanced-Lighting/Gamma-Correction">
    137 				<a href="https://learnopengl.com/Advanced-Lighting/Gamma-Correction">Gamma Correction </a>
    138 			</li>
    139 			<li id="Advanced-Lighting/Shadows">
    140 				<span class="closed">Shadows </span>
    141 				<ol>
    142 					<li id="Advanced-Lighting/Shadows/Shadow-Mapping">
    143 						<a href="https://learnopengl.com/Advanced-Lighting/Shadows/Shadow-Mapping">Shadow Mapping </a>
    144 					</li>
    145 					<li id="Advanced-Lighting/Shadows/Point-Shadows">
    146 						<a href="https://learnopengl.com/Advanced-Lighting/Shadows/Point-Shadows">Point Shadows </a>
    147 					</li>
    148 				</ol>
    149 			</li>
    150 			<li id="Advanced-Lighting/Normal-Mapping">
    151 				<a href="https://learnopengl.com/Advanced-Lighting/Normal-Mapping">Normal Mapping </a>
    152 			</li>
    153 			<li id="Advanced-Lighting/Parallax-Mapping">
    154 				<a href="https://learnopengl.com/Advanced-Lighting/Parallax-Mapping">Parallax Mapping </a>
    155 			</li>
    156 			<li id="Advanced-Lighting/HDR">
    157 				<a href="https://learnopengl.com/Advanced-Lighting/HDR">HDR </a>
    158 			</li>
    159 			<li id="Advanced-Lighting/Bloom">
    160 				<a href="https://learnopengl.com/Advanced-Lighting/Bloom">Bloom </a>
    161 			</li>
    162 			<li id="Advanced-Lighting/Deferred-Shading">
    163 				<a href="https://learnopengl.com/Advanced-Lighting/Deferred-Shading">Deferred Shading </a>
    164 			</li>
    165 			<li id="Advanced-Lighting/SSAO">
    166 				<a href="https://learnopengl.com/Advanced-Lighting/SSAO">SSAO </a>
    167 			</li>
    168 		</ol>
    169 	</li>
    170 	<li id="PBR">
    171 		<span class="closed">PBR </span>
    172 		<ol>
    173 			<li id="PBR/Theory">
    174 				<a href="https://learnopengl.com/PBR/Theory">Theory </a>
    175 			</li>
    176 			<li id="PBR/Lighting">
    177 				<a href="https://learnopengl.com/PBR/Lighting">Lighting </a>
    178 			</li>
    179 			<li id="PBR/IBL">
    180 				<span class="closed">IBL </span>
    181 				<ol>
    182 					<li id="PBR/IBL/Diffuse-irradiance">
    183 						<a href="https://learnopengl.com/PBR/IBL/Diffuse-irradiance">Diffuse irradiance </a>
    184 					</li>
    185 					<li id="PBR/IBL/Specular-IBL">
    186 						<a href="https://learnopengl.com/PBR/IBL/Specular-IBL">Specular IBL </a>
    187 					</li>
    188 				</ol>
    189 			</li>
    190 		</ol>
    191 	</li>
    192 	<li id="In-Practice">
    193 		<span class="closed">In Practice </span>
    194 		<ol>
    195 			<li id="In-Practice/Debugging">
    196 				<a href="https://learnopengl.com/In-Practice/Debugging">Debugging </a>
    197 			</li>
    198 			<li id="In-Practice/Text-Rendering">
    199 				<a href="https://learnopengl.com/In-Practice/Text-Rendering">Text Rendering </a>
    200 			</li>
    201 			<li id="In-Practice/2D-Game">
    202 				<span class="closed">2D Game </span>
    203 				<ol>
    204 					<li id="In-Practice/2D-Game/Breakout">
    205 						<a href="https://learnopengl.com/In-Practice/2D-Game/Breakout">Breakout </a>
    206 					</li>
    207 					<li id="In-Practice/2D-Game/Setting-up">
    208 						<a href="https://learnopengl.com/In-Practice/2D-Game/Setting-up">Setting up </a>
    209 					</li>
    210 					<li id="In-Practice/2D-Game/Rendering-Sprites">
    211 						<a href="https://learnopengl.com/In-Practice/2D-Game/Rendering-Sprites">Rendering Sprites </a>
    212 					</li>
    213 					<li id="In-Practice/2D-Game/Levels">
    214 						<a href="https://learnopengl.com/In-Practice/2D-Game/Levels">Levels </a>
    215 					</li>
    216 					<li id="In-Practice/2D-Game/Collisions">
    217 						<span class="closed">Collisions </span>
    218 						<ol>
    219 							<li id="In-Practice/2D-Game/Collisions/Ball">
    220 								<a href="https://learnopengl.com/In-Practice/2D-Game/Collisions/Ball">Ball </a>
    221 							</li>
    222 							<li id="In-Practice/2D-Game/Collisions/Collision-detection">
    223 								<a href="https://learnopengl.com/In-Practice/2D-Game/Collisions/Collision-detection">Collision detection </a>
    224 							</li>
    225 							<li id="In-Practice/2D-Game/Collisions/Collision-resolution">
    226 								<a href="https://learnopengl.com/In-Practice/2D-Game/Collisions/Collision-resolution">Collision resolution </a>
    227 							</li>
    228 						</ol>
    229 					</li>
    230 					<li id="In-Practice/2D-Game/Particles">
    231 						<a href="https://learnopengl.com/In-Practice/2D-Game/Particles">Particles </a>
    232 					</li>
    233 					<li id="In-Practice/2D-Game/Postprocessing">
    234 						<a href="https://learnopengl.com/In-Practice/2D-Game/Postprocessing">Postprocessing </a>
    235 					</li>
    236 					<li id="In-Practice/2D-Game/Powerups">
    237 						<a href="https://learnopengl.com/In-Practice/2D-Game/Powerups">Powerups </a>
    238 					</li>
    239 					<li id="In-Practice/2D-Game/Audio">
    240 						<a href="https://learnopengl.com/In-Practice/2D-Game/Audio">Audio </a>
    241 					</li>
    242 					<li id="In-Practice/2D-Game/Render-text">
    243 						<a href="https://learnopengl.com/In-Practice/2D-Game/Render-text">Render text </a>
    244 					</li>
    245 					<li id="In-Practice/2D-Game/Final-thoughts">
    246 						<a href="https://learnopengl.com/In-Practice/2D-Game/Final-thoughts">Final thoughts </a>
    247 					</li>
    248 				</ol>
    249 			</li>
    250 		</ol>
    251 	</li>
    252 	<li id="Guest-Articles">
    253 		<span class="closed">Guest Articles </span>
    254 		<ol>
    255 			<li id="Guest-Articles/How-to-publish">
    256 				<a href="https://learnopengl.com/Guest-Articles/How-to-publish">How to publish </a>
    257 			</li>
    258 			<li id="Guest-Articles/2020">
    259 				<span class="closed">2020 </span>
    260 				<ol>
    261 					<li id="Guest-Articles/2020/OIT">
    262 						<span class="closed">OIT </span>
    263 						<ol>
    264 							<li id="Guest-Articles/2020/OIT/Introduction">
    265 								<a href="https://learnopengl.com/Guest-Articles/2020/OIT/Introduction">Introduction </a>
    266 							</li>
    267 							<li id="Guest-Articles/2020/OIT/Weighted-Blended">
    268 								<a href="https://learnopengl.com/Guest-Articles/2020/OIT/Weighted-Blended">Weighted Blended </a>
    269 							</li>
    270 						</ol>
    271 					</li>
    272 					<li id="Guest-Articles/2020/Skeletal-Animation">
    273 						<a href="https://learnopengl.com/Guest-Articles/2020/Skeletal-Animation">Skeletal Animation </a>
    274 					</li>
    275 				</ol>
    276 			</li>
    277 			<li id="Guest-Articles/2021">
    278 				<span class="closed">2021 </span>
    279 				<ol>
    280 					<li id="Guest-Articles/2021/CSM">
    281 						<a href="https://learnopengl.com/Guest-Articles/2021/CSM">CSM </a>
    282 					</li>
    283 					<li id="Guest-Articles/2021/Scene">
    284 						<span class="closed">Scene </span>
    285 						<ol>
    286 							<li id="Guest-Articles/2021/Scene/Scene-Graph">
    287 								<a href="https://learnopengl.com/Guest-Articles/2021/Scene/Scene-Graph">Scene Graph </a>
    288 							</li>
    289 							<li id="Guest-Articles/2021/Scene/Frustum-Culling">
    290 								<a href="https://learnopengl.com/Guest-Articles/2021/Scene/Frustum-Culling">Frustum Culling </a>
    291 							</li>
    292 						</ol>
    293 					</li>
    294 					<li id="Guest-Articles/2021/Tessellation">
    295 						<span class="closed">Tessellation </span>
    296 						<ol>
    297 							<li id="Guest-Articles/2021/Tessellation/Height-map">
    298 								<a href="https://learnopengl.com/Guest-Articles/2021/Tessellation/Height-map">Height map </a>
    299 							</li>
    300 						</ol>
    301 					</li>
    302 				</ol>
    303 			</li>
    304 		</ol>
    305 	</li>
    306 	<li id="Code-repository">
    307 		<a href="https://learnopengl.com/Code-repository">Code repository </a>
    308 	</li>
    309 	<li id="Translations">
    310 		<a href="https://learnopengl.com/Translations">Translations </a>
    311 	</li>
    312 	<li id="About">
    313 		<a href="https://learnopengl.com/About">About </a>
    314 	</li>
    315 </ol>
    316 	</nav>
    317 	<main>
    318     <div id="content">
    319     <h1 id="content-title">Advanced GLSL</h1>
    320 <h1 id="content-url" style='display:none;'>Advanced-OpenGL/Advanced-GLSL</h1>
    321 <p>
    322   This chapter won't really show you super advanced cool new features that give an enormous boost to your scene's visual quality. This chapter goes more or less into some interesting aspects of GLSL and some nice tricks that may help you in your future endeavors. Basically some <em>good to knows</em> and <em>features that may make your life easier</em> when creating OpenGL applications in combination with GLSL.
    323 </p>
    324 
    325 <p>
    326   We'll discuss some interesting <def>built-in variables</def>, new ways to organize shader input and output, and a very useful tool called <def>uniform buffer objects</def>.
    327 </p>
    328 
    329 <h1>GLSL's built-in variables</h1>
    330 <p>
    331   Shaders are extremely pipelined, if we need data from any other source outside of the current shader we'll have to pass data around. We learned to do this via vertex attributes, uniforms, and samplers. There are however a few extra variables defined by GLSL prefixed with <code>gl_</code> that give us an extra means to gather and/or write data. We've already seen two of them in the chapters so far: <var>gl_Position</var> that is the output vector of the vertex shader, and the fragment shader's <var>gl_FragCoord</var>.  
    332 </p>
    333 
    334 <p>
    335   We'll discuss a few interesting built-in input and output variables that are built-in in GLSL and explain how they may benefit us. Note that we won't discuss all built-in variables that exist in GLSL so if you want to see all built-in variables you can check OpenGL's <a href="https://www.khronos.org/opengl/wiki/Built-in_Variable_(GLSL)" target="_blank">wiki</a>.
    336 </p>
    337 
    338 <h2>Vertex shader variables</h2>
    339 <p>
    340   We've already seen <var>gl_Position</var> which is the clip-space output position vector of the vertex shader. Setting <var>gl_Position</var> in the vertex shader is a strict requirement if you want to render anything on the screen. Nothing we haven't seen before.
    341 </p>
    342 
    343 <h3>gl_PointSize</h3>
    344 <p>
    345   One of the render primitives we're able to choose from is <var>GL_POINTS</var> in which case each single vertex is a primitive and rendered as a point. It is possible to set the size of the points being rendered via OpenGL's <fun>glPointSize</fun> function, but we can also influence this value in the vertex shader.
    346 </p>
    347 
    348 <p>
    349   One output variable defined by GLSL is called <var>gl_PointSize</var> that is a <fun>float</fun> variable where you can set the point's width and height in pixels. By setting the point's size in the vertex shader we get per-vertex control over this point's dimensions.
    350 </p>
    351 
    352 <p>
    353   Influencing the point sizes in the vertex shader is disabled by default, but if you want to enable this you'll have to enable OpenGL's <var>GL_PROGRAM_POINT_SIZE</var>:
    354 </p>
    355 
    356 <pre><code>
    357 <function id='60'>glEnable</function>(GL_PROGRAM_POINT_SIZE);  
    358 </code></pre>
    359 
    360 <p>
    361   A simple example of influencing point sizes is by setting the point size equal to the clip-space position's z value which is equal to the vertex's distance to the viewer. The point size should then increase the further we are from the vertices as the viewer.
    362 </p>
    363 
    364 <pre><code>
    365 void main()
    366 {
    367     gl_Position = projection * view * model * vec4(aPos, 1.0);    
    368     gl_PointSize = gl_Position.z;    
    369 }  
    370 </code></pre>
    371 
    372 <p>
    373   The result is that the points we've drawn are rendered larger the more we move away from them:
    374 </p>
    375 
    376 <img src="/img/advanced/advanced_glsl_pointsize.png" class="clean" alt="Points in OpenGL drawn with their gl_PointSize influenced in the vertex shader"/>
    377 
    378 <p>
    379   You can imagine that varying the point size per vertex is interesting for techniques like particle generation.
    380 </p>
    381 
    382 <h3>gl_VertexID</h3>
    383 <p>
    384   The <var>gl_Position</var> and <var>gl_PointSize</var> are <em>output variables</em> since their value is read as output from the vertex shader; we can influence the result by writing to them. The vertex shader also gives us an interesting <em>input variable</em>, that we can only read from, called <var>gl_VertexID</var>.
    385 </p>
    386 
    387 <p>
    388   The integer variable <var>gl_VertexID</var> holds the current ID of the vertex we're drawing. When doing <em>indexed rendering</em> (with <fun><function id='2'>glDrawElements</function></fun>) this variable holds the current index of the vertex we're drawing. When drawing without indices (via <fun><function id='1'>glDrawArrays</function></fun>) this variable holds the number of the currently processed vertex since the start of the render call.
    389 </p>
    390 
    391 <h2>Fragment shader variables</h2>
    392 <p>
    393   Within the fragment shader we also have access to some interesting variables. GLSL gives us two interesting input variables called <var>gl_FragCoord</var> and <var>gl_FrontFacing</var>.
    394 </p>
    395 
    396 <h3>gl_FragCoord</h3>
    397 <p>
    398   We've seen the <var>gl_FragCoord</var> a couple of times before during the discussion of depth testing, because the <code>z</code> component of the <var>gl_FragCoord</var> vector is equal to the depth value of that particular fragment. However, we can also use the x and y component of that vector for some interesting effects.
    399 </p>
    400 
    401 <p>
    402   The <var>gl_FragCoord</var>'s <code>x</code> and <code>y</code> component are the window- or screen-space coordinates of the fragment, originating from the bottom-left of the window. We specified a render window of 800x600 with <fun><function id='22'>glViewport</function></fun> so the screen-space coordinates of the fragment will have <code>x</code> values between 0 and 800, and <code>y</code> values between 0 and 600.
    403 </p>
    404 
    405 <p>
    406   Using the fragment shader we could calculate a different color value based on the screen coordinate of the fragment. A common usage for the <var>gl_FragCoord</var> variable is for comparing visual output of different fragment calculations, as usually seen in tech demos. We could for example split the screen in two by rendering one output to the left side of the window and another output to the right side of the window. An example fragment shader that outputs a different color based on the fragment's screen coordinates is given below:
    407 </p>
    408 
    409 <pre><code>
    410 void main()
    411 {             
    412     if(gl_FragCoord.x &lt; 400)
    413         FragColor = vec4(1.0, 0.0, 0.0, 1.0);
    414     else
    415         FragColor = vec4(0.0, 1.0, 0.0, 1.0);        
    416 }  
    417 </code></pre>
    418 
    419 <p>
    420   Because the width of the window is equal to 800, whenever a pixel's x-coordinate is less than 400 it must be at the left side of the window and we'll give that fragment a different color.
    421 </p>
    422 
    423 <img src="/img/advanced/advanced_glsl_fragcoord.png" class="clean" alt="Cube in OpenGL drawn with 2 colors using gl_FragCoord"/>
    424 
    425 <p>
    426   We can now calculate two completely different fragment shader results and display each of them on a different side of the window. This is great for testing out different lighting techniques for example.
    427 </p>
    428 
    429 <h3>gl_FrontFacing</h3>
    430 <p>
    431   Another interesting input variable in the fragment shader is the <var>gl_FrontFacing</var> variable. In the <a href="https://learnopengl.com/Advanced-OpenGL/Face-culling" target="_blank">face culling</a> chapter we mentioned that OpenGL is able to figure out if a face is a front or back face due to the winding order of the vertices. The <var>gl_FrontFacing</var> variable tells us if the current fragment is part of a front-facing or a back-facing face. We could, for example, decide to output different colors for all back faces.
    432 </p>
    433 
    434 <p>
    435   The <var>gl_FrontFacing</var> variable is a <fun>bool</fun> that is <code>true</code> if the fragment is part of a front face and <code>false</code> otherwise. We could create a cube this way with a different texture on the inside than on the outside:
    436 </p>
    437 
    438 <pre><code>
    439 #version 330 core
    440 out vec4 FragColor;
    441   
    442 in vec2 TexCoords;
    443 
    444 uniform sampler2D frontTexture;
    445 uniform sampler2D backTexture;
    446 
    447 void main()
    448 {             
    449     if(gl_FrontFacing)
    450         FragColor = texture(frontTexture, TexCoords);
    451     else
    452         FragColor = texture(backTexture, TexCoords);
    453 }  
    454 </code></pre>
    455 
    456 <p>
    457   If we take a peek inside the container we can now see a different texture being used.
    458 </p>
    459 
    460 <img src="/img/advanced/advanced_glsl_frontfacing.png" class="clean" alt="OpenGL container using two different textures via gl_FrontFacing"/>
    461 
    462 <p>
    463   Note that if you enabled face culling you won't be able to see any faces inside the container and using <var>gl_FrontFacing</var> would then be pointless.
    464 </p>
    465 
    466 <h3>gl_FragDepth</h3>
    467 <p>
    468   The input variable <var>gl_FragCoord</var> is an input variable that allows us to read screen-space coordinates and get the depth value of the current fragment, but it is a <def>read-only</def> variable. We can't influence the screen-space coordinates of the fragment, but it is possible to set the depth value of the fragment. GLSL gives us an output variable called <var>gl_FragDepth</var> that we can use to manually set the depth value of the fragment within the shader.
    469 </p>
    470 
    471 <p>
    472   To set the depth value in the shader we write any value between <code>0.0</code> and <code>1.0</code> to the output variable:
    473 </p>
    474 
    475 <pre><code>
    476 gl_FragDepth = 0.0; // this fragment now has a depth value of 0.0
    477 </code></pre>
    478 
    479 <p>
    480   If the shader does not write anything to <var>gl_FragDepth</var>, the variable will automatically take its value from <code>gl_FragCoord.z</code>.
    481 </p>
    482 
    483 <p>
    484   Setting the depth value manually has a major disadvantage however. That is because OpenGL disables <def>early depth testing</def> (as discussed in the <a href="https://learnopengl.com/Advanced-OpenGL/Depth-testing" target="_blank">depth testing</a> chapter) as soon as we write to <var>gl_FragDepth</var> in the fragment shader. It is disabled, because OpenGL cannot know what depth value the fragment will have <em>before</em> we run the fragment shader, since the fragment shader may actually change this value.
    485 </p>
    486 
    487 <p>
    488   By writing to <var>gl_FragDepth</var> you should take this performance penalty into consideration. From OpenGL 4.2 however, we can still sort of mediate between both sides by redeclaring the <var>gl_FragDepth</var> variable at the top of the fragment shader with a <def>depth condition</def>:
    489 </p>
    490 
    491 <pre><code>
    492 layout (depth_&ltcondition&gt;) out float gl_FragDepth;
    493 </code></pre>
    494 
    495 <p>
    496   This <code>condition</code> can take the following values:
    497 </p>
    498 
    499 <table>
    500   <tr>
    501   	<th>Condition</th>
    502   	<th>Description</th>
    503   </tr>  
    504   <tr>
    505     <td><code>any</code></td>
    506  	<td>The default value. Early depth testing is disabled.</td>
    507   </tr>
    508   <tr>
    509     <td><code>greater</code></td>
    510     <td>You can only make the depth value larger compared to <code>gl_FragCoord.z</code>.</td>
    511   </tr>
    512   <tr>
    513     <td><code>less</code></td>
    514  	<td>You can only make the depth value smaller compared to <code>gl_FragCoord.z</code>.</td>
    515   </tr>
    516   <tr>
    517     <td><code>unchanged</code></td>
    518     <td>If you write to <code>gl_FragDepth</code>, you will write exactly <code>gl_FragCoord.z</code>.</td>
    519   </tr>
    520 </table>
    521 
    522 <p>
    523   By specifying <code>greater</code> or <code>less</code> as the depth condition, OpenGL can make the assumption that you'll only write depth values larger or smaller than the fragment's depth value. This way OpenGL is still able to do early depth testing when the depth buffer value is part of the other direction of <code>gl_FragCoord.z</code>.  
    524 </p>
    525 
    526 <p>
    527   An example of where we increase the depth value in the fragment shader, but still want to preserve some of the early depth testing is shown in the fragment shader below:
    528 </p>
    529 
    530 <pre><code>
    531 #version 420 core // note the GLSL version!
    532 out vec4 FragColor;
    533 layout (depth_greater) out float gl_FragDepth;
    534 
    535 void main()
    536 {             
    537     FragColor = vec4(1.0);
    538     gl_FragDepth = gl_FragCoord.z + 0.1;
    539 }  
    540 </code></pre>
    541 
    542 <p>
    543   Do note that this feature is only available from OpenGL version 4.2 or higher.
    544 </p>
    545 
    546 <h1>Interface blocks</h1>
    547 <p>
    548   So far, every time we sent data from the vertex to the fragment shader we declared several matching input/output variables. Declaring these one at a time is the easiest way to send data from one shader to another, but as applications become larger you probably want to send more than a few variables over.
    549 </p>
    550 
    551 <p>
    552   To help us organize these variables GLSL offers us something called <def>interface blocks</def> that allows us to group variables together. The declaration of such an interface block looks a lot like a <fun>struct</fun> declaration, except that it is now declared using an <fun>in</fun> or <fun>out</fun> keyword based on the block being an input or an output block.
    553 </p>
    554 
    555 <pre><code>
    556 #version 330 core
    557 layout (location = 0) in vec3 aPos;
    558 layout (location = 1) in vec2 aTexCoords;
    559 
    560 uniform mat4 model;
    561 uniform mat4 view;
    562 uniform mat4 projection;
    563 
    564 out VS_OUT
    565 {
    566     vec2 TexCoords;
    567 } vs_out;
    568 
    569 void main()
    570 {
    571     gl_Position = projection * view * model * vec4(aPos, 1.0);    
    572     vs_out.TexCoords = aTexCoords;
    573 }  
    574 </code></pre>
    575 
    576 <p>
    577   This time we declared an interface block called <var>vs_out</var> that groups together all the output variables we want to send to the next shader. This is kind of a trivial example, but you can imagine that this helps organize your shaders' inputs/outputs. It is also useful when we want to group shader input/output into arrays as we'll see in the <a href="https://learnopengl.com/Advanced-OpenGL/Geometry-Shader" target="_blank">next</a> chapter about geometry shaders.
    578 </p>
    579 
    580 <p>
    581   Then we also need to declare an input interface block in the next shader which is the fragment shader. The <def>block name</def> (<fun>VS_OUT</fun>) should be the same in the fragment shader, but the <def>instance name</def> (<var>vs_out</var> as used in the vertex shader) can be anything we like - avoiding confusing names like <var>vs_out</var> for a fragment struct containing input values.
    582 </p>
    583 
    584 <pre><code>
    585 #version 330 core
    586 out vec4 FragColor;
    587 
    588 in VS_OUT
    589 {
    590     vec2 TexCoords;
    591 } fs_in;
    592 
    593 uniform sampler2D texture;
    594 
    595 void main()
    596 {             
    597     FragColor = texture(texture, fs_in.TexCoords);   
    598 } 
    599 </code></pre>
    600 
    601 <p>
    602   As long as both interface block names are equal, their corresponding input and output is matched together. This is another useful feature that helps organize your code and proves useful when crossing between certain shader stages like the geometry shader.
    603 </p>
    604 
    605 <h1>Uniform buffer objects</h1>
    606 <p>
    607   We've been using OpenGL for quite a while now and learned some pretty cool tricks, but also a few annoyances. For example, when using more than one shader we continuously have to set uniform variables where most of them are exactly the same for each shader.
    608 </p>
    609 
    610 <p>
    611   OpenGL gives us a tool called <def>uniform buffer objects</def> that allow us to declare a set of <em>global</em> uniform variables that remain the same over any number of shader programs. When using uniform buffer objects we set the relevant uniforms only <strong>once</strong> in fixed GPU memory. We do still have to manually set the uniforms that are unique per shader. Creating and configuring a uniform buffer object requires a bit of work though.
    612 </p>
    613 
    614 <p>
    615   Because a uniform buffer object is a buffer like any other buffer we can create one via <fun><function id='12'>glGenBuffers</function></fun>, bind it to the <var>GL_UNIFORM_BUFFER</var> buffer target and store all the relevant uniform data into the buffer. There are certain rules as to how the data for uniform buffer objects should be stored and we'll get to that later. First, we'll take a simple vertex shader and store our <var>projection</var> and <var>view</var> matrix in a so called <def>uniform block</def>:
    616 </p>
    617 
    618 <pre><code>
    619 #version 330 core
    620 layout (location = 0) in vec3 aPos;
    621 
    622 layout (std140) uniform Matrices
    623 {
    624     mat4 projection;
    625     mat4 view;
    626 };
    627 
    628 uniform mat4 model;
    629 
    630 void main()
    631 {
    632     gl_Position = projection * view * model * vec4(aPos, 1.0);
    633 }  
    634 </code></pre>
    635 
    636 <p>
    637   In most of our samples we set a projection and view uniform matrix every frame for each shader we're using. This is a perfect example of where uniform buffer objects become useful since now we only have to store these matrices once. 
    638 </p>
    639 
    640 <p>
    641   Here we declared a uniform block called <var>Matrices</var> that stores two 4x4 matrices. Variables in a uniform block can be directly accessed without the block name as a prefix. Then we store these matrix values in a buffer somewhere in the OpenGL code and each shader that declares this uniform block has access to the matrices.
    642 </p> 
    643 
    644 <p>
    645   You're probably wondering right now what the <code>layout</code> <code>(std140)</code> statement means. What this says is that the currently defined uniform block uses a specific memory layout for its content; this statement sets the <def>uniform block layout</def>.
    646 </p>
    647 
    648 <h2>Uniform block layout</h2>
    649 <p>
    650   The content of a uniform block is stored in a buffer object, which is effectively nothing more than a reserved piece of global GPU memory. Because this piece of memory holds no information on what kind of data it holds, we need to tell OpenGL what parts of the memory correspond to which uniform variables in the shader. 
    651 </p>
    652 
    653 <p>
    654   Imagine the following uniform block in a shader:
    655 </p>
    656 
    657 <pre><code>
    658 layout (std140) uniform ExampleBlock
    659 {
    660     float value;
    661     vec3  vector;
    662     mat4  matrix;
    663     float values[3];
    664     bool  boolean;
    665     int   integer;
    666 };  
    667 </code></pre>
    668 
    669 <p>
    670   What we want to know is the size (in bytes) and the offset (from the start of the block) of each of these variables so we can place them in the buffer in their respective order. The size of each of the elements is clearly stated in OpenGL and directly corresponds to C++ data types; vectors and matrices being (large) arrays of floats. What OpenGL doesn't clearly state is the <def>spacing</def> between the variables. This allows the hardware to position or pad variables as it sees fit. The hardware is able to place a <fun>vec3</fun> adjacent to a <fun>float</fun> for example. Not all hardware can handle this and pads the <fun>vec3</fun> to an array of 4 floats before appending the <fun>float</fun>. A great feature, but inconvenient for us.
    671 </p>
    672 
    673 <p>
    674   By default, GLSL uses a uniform memory layout called a <def>shared</def> layout - shared because once the offsets are defined by the hardware, they are consistently <em>shared</em> between multiple programs. With a shared layout GLSL is allowed to reposition the uniform variables for optimization as long as the variables' order remains intact. Because we don't know at what offset each uniform variable will be we don't know how to precisely fill our uniform buffer. We can query this information with functions like <fun>glGetUniformIndices</fun>, but that's not the approach we're going to take in this chapter.
    675 </p>
    676 
    677 <p>
    678   While a shared layout gives us some space-saving optimizations, we'd need to query the offset for each uniform variable which translates to a lot of work. The general practice however is to not use the shared layout, but to use the <def>std140</def> layout. The std140 layout <strong>explicitly</strong> states the memory layout for each variable type by standardizing their respective offsets governed by a set of rules. Since this is standardized we can manually figure out the offsets for each variable. 
    679 </p>
    680 
    681 <p>
    682   Each variable has a <def>base alignment</def> equal to the space a variable takes (including padding) within a uniform block using the std140 layout rules. For each variable, we calculate its <def>aligned offset</def>: the byte offset of a variable from the start of the block. The aligned byte offset of a variable <strong>must</strong> be equal to a multiple of its base alignment. This is a bit of a mouthful, but we'll get to see some examples soon enough to clear things up.
    683 </p>
    684 
    685 <p>
    686   The exact layout rules can be found at OpenGL's uniform buffer specification <a href="http://www.opengl.org/registry/specs/ARB/uniform_buffer_object.txt" target="_blank">here</a>, but we'll list the most common rules below. Each variable type in GLSL such as <fun>int</fun>, <fun>float</fun> and <fun>bool</fun> are defined to be four-byte quantities with each entity of 4 bytes represented as <code>N</code>. 
    687 </p>
    688 
    689 <table>
    690   <tr>
    691     <th>Type</th>
    692     <th>Layout rule</th>
    693   </tr>
    694   
    695   <tr>
    696     <td>Scalar e.g. <fun>int</fun> or <fun>bool</fun></td>
    697     <td>Each scalar has a base alignment of N.</td>
    698   </tr>
    699   <tr>
    700     <td>Vector</td>
    701     <td>Either 2N or 4N. This means that a <fun>vec3</fun> has a base alignment of 4N.</td>
    702   </tr>
    703   <tr>
    704     <td>Array of scalars or vectors</td>
    705     <td>Each element has a base alignment equal to that of a <fun>vec4</fun>.</td>
    706   </tr>
    707   <tr>
    708     <td>Matrices</td>
    709     <td>Stored as a large array of column vectors, where each of those vectors has a base alignment of <fun>vec4</fun>.</td>
    710   </tr>
    711   <tr>
    712     <td>Struct</td>
    713     <td>Equal to the computed size of its elements according to the previous rules, but padded to a multiple of the size of a <fun>vec4</fun>.</td>
    714   </tr>    
    715 </table>
    716 
    717 <p>
    718   Like most of OpenGL's specifications it's easier to understand with an example. We're taking the uniform block called <var>ExampleBlock</var> we introduced earlier and calculate the aligned offset for each of its members using the std140 layout:
    719 </p>
    720 
    721 <pre><code>
    722 layout (std140) uniform ExampleBlock
    723 {
    724                      // base alignment  // aligned offset
    725     float value;     // 4               // 0 
    726     vec3 vector;     // 16              // 16  (offset must be multiple of 16 so 4->16)
    727     mat4 matrix;     // 16              // 32  (column 0)
    728                      // 16              // 48  (column 1)
    729                      // 16              // 64  (column 2)
    730                      // 16              // 80  (column 3)
    731     float values[3]; // 16              // 96  (values[0])
    732                      // 16              // 112 (values[1])
    733                      // 16              // 128 (values[2])
    734     bool boolean;    // 4               // 144
    735     int integer;     // 4               // 148
    736 }; 
    737 </code></pre>
    738 
    739 <p>
    740   As an exercise, try to calculate the offset values yourself and compare them to this table. With these calculated offset values, based on the rules of the std140 layout, we can fill the buffer with data at the appropriate offsets using functions like <fun><function id='90'>glBufferSubData</function></fun>. While not the most efficient, the std140 layout does guarantee us that the memory layout remains the same over each program that declared this uniform block.
    741 </p>
    742 
    743 <p>
    744   By adding the statement <code>layout</code> <code>(std140)</code> in the definition of the uniform block we tell OpenGL that this uniform block uses the std140 layout. There are two other layouts to choose from that require us to query each offset before filling the buffers. We've already seen the <code>shared</code> layout, with the other remaining layout being <code>packed</code>. When using the <code>packed</code> layout, there is no guarantee that the layout remains the same between programs (not shared) because it allows the compiler to optimize uniform variables away from the uniform block which may differ per shader.
    745 </p>
    746 
    747 <h2>Using uniform buffers</h2>
    748 <p>
    749   We've defined uniform blocks and specified their memory layout, but we haven't discussed how to actually use them yet.
    750 </p>
    751 
    752 <p>
    753   First, we need to create a uniform buffer object which is done via the familiar <fun><function id='12'>glGenBuffers</function></fun>. Once we have a buffer object we bind it to the <var>GL_UNIFORM_BUFFER</var> target and allocate enough memory by calling <fun><function id='31'>glBufferData</function></fun>.
    754 </p>
    755 
    756 <pre><code>
    757 unsigned int uboExampleBlock;
    758 <function id='12'>glGenBuffers</function>(1, &uboExampleBlock);
    759 <function id='32'>glBindBuffer</function>(GL_UNIFORM_BUFFER, uboExampleBlock);
    760 <function id='31'>glBufferData</function>(GL_UNIFORM_BUFFER, 152, NULL, GL_STATIC_DRAW); // allocate 152 bytes of memory
    761 <function id='32'>glBindBuffer</function>(GL_UNIFORM_BUFFER, 0);
    762 </code></pre>
    763 
    764 <p>
    765   Now whenever we want to update or insert data into the buffer, we bind to <var>uboExampleBlock</var> and use <fun><function id='90'>glBufferSubData</function></fun> to update its memory. We only have to update this uniform buffer once, and all shaders that use this buffer now use its updated data. But, how does OpenGL know what uniform buffers correspond to which uniform blocks?
    766 </p>
    767 
    768 <p>
    769   In the OpenGL context there is a number of <def>binding points</def> defined where we can link a uniform buffer to. Once we created a uniform buffer we link it to one of those binding points and we also link the uniform block in the shader to the same binding point, effectively linking them together. The following diagram illustrates this:
    770 </p>
    771 
    772 <img src="/img/advanced/advanced_glsl_binding_points.png" class="clean" alt="Diagram of uniform binding points in OpenGL"/>
    773 
    774 <p>
    775   As you can see we can bind multiple uniform buffers to different binding points. Because shader A and shader B both have a uniform block linked to the same binding point <code>0</code>, their uniform blocks share the same uniform data found in <var>uboMatrices</var>; a requirement being that both shaders defined the same <var>Matrices</var> uniform block.
    776 </p>
    777 
    778 <p>
    779   To set a shader uniform block to a specific binding point we call <fun><function id='95'><function id='44'>glUniform</function>BlockBinding</function></fun> that takes a program object, a uniform block index, and the binding point to link to. The <def>uniform block index</def> is a location index of the defined uniform block in the shader. This can be retrieved via a call to <fun><function id='94'>glGetUniformBlockIndex</function></fun> that accepts a program object and the name of the uniform block. We can set the <var>Lights</var> uniform block from the diagram to binding point <code>2</code> as follows:
    780 </p>
    781 
    782 <pre><code>
    783 unsigned int lights_index = <function id='94'>glGetUniformBlockIndex</function>(shaderA.ID, "Lights");   
    784 <function id='95'><function id='44'>glUniform</function>BlockBinding</function>(shaderA.ID, lights_index, 2);
    785 </code></pre>
    786 
    787 <p>
    788   Note that we have to repeat this process for <strong>each</strong> shader.
    789 </p>
    790 
    791 <note>
    792   From OpenGL version 4.2 and onwards it is also possible to store the binding point of a uniform block explicitly in the shader by adding another layout specifier, saving us the calls to <fun><function id='94'>glGetUniformBlockIndex</function></fun> and <fun><function id='95'><function id='44'>glUniform</function>BlockBinding</function></fun>. The following code sets the binding point of the <var>Lights</var> uniform block explicitly:	
    793 <pre class="cpp"><code>
    794 layout(std140, binding = 2) uniform Lights { ... };
    795 </code></pre>  
    796 </note>
    797 
    798 <p>
    799   Then we also need to bind the uniform buffer object to the same binding point and this can be accomplished with either <fun><function id='96'><function id='32'>glBindBuffer</function>Base</function></fun> or <fun><function id='97'><function id='32'>glBindBuffer</function>Range</function></fun>.
    800 </p>
    801 
    802 <pre><code>
    803 <function id='96'><function id='32'>glBindBuffer</function>Base</function>(GL_UNIFORM_BUFFER, 2, uboExampleBlock); 
    804 // or
    805 <function id='97'><function id='32'>glBindBuffer</function>Range</function>(GL_UNIFORM_BUFFER, 2, uboExampleBlock, 0, 152);
    806 </code></pre>
    807 
    808 <p>
    809   The function <fun><function id='96'><function id='32'>glBindbuffer</function>Base</function></fun> expects a target, a binding point index and a uniform buffer object. This function links <var>uboExampleBlock</var> to binding point <code>2</code>; from this point on, both sides of the binding point are linked. You can also use <fun><function id='97'><function id='32'>glBindBuffer</function>Range</function></fun> that expects an extra offset and size parameter - this way you can bind only a specific range of the uniform buffer to a binding point. Using <fun><function id='97'><function id='32'>glBindBuffer</function>Range</function></fun> you could have multiple different uniform blocks linked to a single uniform buffer object.
    810 </p>
    811 
    812 <p>
    813   Now that everything is set up, we can start adding data to the uniform buffer. We could add all the data as a single byte array, or update parts of the buffer whenever we feel like it using  <fun><function id='90'>glBufferSubData</function></fun>. To update the uniform variable <var>boolean</var> we could update the uniform buffer object as follows:
    814 </p>
    815 
    816 <pre><code>
    817 <function id='32'>glBindBuffer</function>(GL_UNIFORM_BUFFER, uboExampleBlock);
    818 int b = true; // bools in GLSL are represented as 4 bytes, so we store it in an integer
    819 <function id='90'>glBufferSubData</function>(GL_UNIFORM_BUFFER, 144, 4, &b); 
    820 <function id='32'>glBindBuffer</function>(GL_UNIFORM_BUFFER, 0);
    821 </code></pre>
    822 
    823 <p>
    824   And the same procedure applies for all the other uniform variables inside the uniform block, but with different range arguments.
    825 </p>
    826 
    827 <h2>A simple example</h2>
    828 <p>
    829   So let's demonstrate a real example of uniform buffer objects. If we look back at all the previous code samples we've continually been using 3 matrices: the projection, view and model matrix. Of all those matrices, only the model matrix changes frequently. If we have multiple shaders that use this same set of matrices, we'd probably be better off using uniform buffer objects.
    830 </p>
    831 
    832 <p>
    833   We're going to store the projection and view matrix in a uniform block called <var>Matrices</var>. We're not going to store the model matrix in there since the model matrix tends to change frequently between shaders, so we wouldn't really benefit from uniform buffer objects.
    834 </p>
    835 
    836 <pre><code>
    837 #version 330 core
    838 layout (location = 0) in vec3 aPos;
    839 
    840 layout (std140) uniform Matrices
    841 {
    842     mat4 projection;
    843     mat4 view;
    844 };
    845 uniform mat4 model;
    846 
    847 void main()
    848 {
    849     gl_Position = projection * view * model * vec4(aPos, 1.0);
    850 }  
    851 </code></pre>
    852 
    853 <p>
    854   Not much going on here, except that we now use a uniform block with a std140 layout. What we're going to do in our sample application is display 4 cubes where each cube is displayed with a different shader program. Each of the 4 shader programs uses the same vertex shader, but has a unique fragment shader that only outputs a single color that differs per shader.
    855 </p>
    856 
    857 <p>
    858   First, we set the uniform block of the vertex shaders equal to binding point <code>0</code>. Note that we have to do this for each shader:
    859 </p>
    860 
    861 <pre><code>
    862 unsigned int uniformBlockIndexRed    = <function id='94'>glGetUniformBlockIndex</function>(shaderRed.ID, "Matrices");
    863 unsigned int uniformBlockIndexGreen  = <function id='94'>glGetUniformBlockIndex</function>(shaderGreen.ID, "Matrices");
    864 unsigned int uniformBlockIndexBlue   = <function id='94'>glGetUniformBlockIndex</function>(shaderBlue.ID, "Matrices");
    865 unsigned int uniformBlockIndexYellow = <function id='94'>glGetUniformBlockIndex</function>(shaderYellow.ID, "Matrices");  
    866   
    867 <function id='95'><function id='44'>glUniform</function>BlockBinding</function>(shaderRed.ID,    uniformBlockIndexRed, 0);
    868 <function id='95'><function id='44'>glUniform</function>BlockBinding</function>(shaderGreen.ID,  uniformBlockIndexGreen, 0);
    869 <function id='95'><function id='44'>glUniform</function>BlockBinding</function>(shaderBlue.ID,   uniformBlockIndexBlue, 0);
    870 <function id='95'><function id='44'>glUniform</function>BlockBinding</function>(shaderYellow.ID, uniformBlockIndexYellow, 0);
    871 </code></pre>
    872 
    873 <p>
    874   Next we create the actual uniform buffer object and bind that buffer to binding point <code>0</code>:
    875 </p>
    876 
    877 <pre><code>
    878 unsigned int uboMatrices
    879 <function id='12'>glGenBuffers</function>(1, &uboMatrices);
    880   
    881 <function id='32'>glBindBuffer</function>(GL_UNIFORM_BUFFER, uboMatrices);
    882 <function id='31'>glBufferData</function>(GL_UNIFORM_BUFFER, 2 * sizeof(glm::mat4), NULL, GL_STATIC_DRAW);
    883 <function id='32'>glBindBuffer</function>(GL_UNIFORM_BUFFER, 0);
    884   
    885 <function id='97'><function id='32'>glBindBuffer</function>Range</function>(GL_UNIFORM_BUFFER, 0, uboMatrices, 0, 2 * sizeof(glm::mat4));
    886 </code></pre>
    887 
    888 <p>
    889   First we allocate enough memory for our buffer which is equal to 2 times the size of <fun>glm::mat4</fun>. The size of GLM's matrix types correspond directly to <fun>mat4</fun> in GLSL. Then we link a specific range of the buffer, in this case the entire buffer, to binding point <code>0</code>.
    890 </p>
    891 
    892 <p>
    893   Now all that's left to do is fill the buffer. If we keep the <em>field of view</em> value constant of the projection matrix (so no more camera zoom) we only have to update it once in our application - this means we only have to insert this into the buffer only once as well. Because we already allocated enough memory in the buffer object we can use <fun><function id='90'>glBufferSubData</function></fun> to store the projection matrix before we enter the render loop:
    894 </p>
    895 
    896 <pre><code>
    897 glm::mat4 projection = <function id='58'>glm::perspective</function>(<function id='63'>glm::radians</function>(45.0f), (float)width/(float)height, 0.1f, 100.0f);
    898 <function id='32'>glBindBuffer</function>(GL_UNIFORM_BUFFER, uboMatrices);
    899 <function id='90'>glBufferSubData</function>(GL_UNIFORM_BUFFER, 0, sizeof(glm::mat4), glm::value_ptr(projection));
    900 <function id='32'>glBindBuffer</function>(GL_UNIFORM_BUFFER, 0);  
    901 </code></pre>
    902 
    903 <p>
    904   Here we store the first half of the uniform buffer with the projection matrix. Then before we render the objects each frame we update the second half of the buffer with the view matrix:
    905 </p>
    906 
    907 <pre><code>
    908 glm::mat4 view = camera.GetViewMatrix();	       
    909 <function id='32'>glBindBuffer</function>(GL_UNIFORM_BUFFER, uboMatrices);
    910 <function id='90'>glBufferSubData</function>(GL_UNIFORM_BUFFER, sizeof(glm::mat4), sizeof(glm::mat4), glm::value_ptr(view));
    911 <function id='32'>glBindBuffer</function>(GL_UNIFORM_BUFFER, 0);  
    912 </code></pre>
    913 
    914 <p>
    915   And that's it for uniform buffer objects. Each vertex shader that contains a <var>Matrices</var> uniform block will now contain the data stored in <var>uboMatrices</var>. So if we now were to draw 4 cubes using 4 different shaders, their projection and view matrix should be the same:
    916 </p>
    917 
    918 <pre><code>
    919 <function id='27'>glBindVertexArray</function>(cubeVAO);
    920 shaderRed.use();
    921 glm::mat4 model = glm::mat4(1.0f);
    922 model = <function id='55'>glm::translate</function>(model, glm::vec3(-0.75f, 0.75f, 0.0f));	// move top-left
    923 shaderRed.setMat4("model", model);
    924 <function id='1'>glDrawArrays</function>(GL_TRIANGLES, 0, 36);        
    925 // ... draw Green Cube
    926 // ... draw Blue Cube
    927 // ... draw Yellow Cube	  
    928 </code></pre>
    929 
    930 <p>
    931   The only uniform we still need to set is the <var>model</var> uniform. Using uniform buffer objects in a scenario like this saves us from quite a few uniform calls per shader. The result looks something like this:
    932 </p>
    933 
    934 <img src="/img/advanced/advanced_glsl_uniform_buffer_objects.png" class="clean" alt="Image of 4 cubes with their uniforms set via OpenGL's uniform buffer objects"/>
    935 
    936 <p>
    937   Each of the cubes is moved to one side of the window by translating the model matrix and, thanks to the different fragment shaders, their colors differ per object. This is a relatively simple scenario of where we could use uniform buffer objects, but any large rendering application can have over hundreds of shader programs active which is where uniform buffer objects really start to shine.
    938 </p>
    939 
    940 <p>
    941   You can find the full source code of the uniform example application <a href="/code_viewer_gh.php?code=src/4.advanced_opengl/8.advanced_glsl_ubo/advanced_glsl_ubo.cpp" target="_blank">here</a>.
    942 </p>
    943 
    944 <p>
    945   Uniform buffer objects have several advantages over single uniforms. First, setting a lot of uniforms at once is faster than setting multiple uniforms one at a time. Second, if you want to change the same uniform over several shaders, it is much easier to change a uniform once in a uniform buffer. One last advantage that is not immediately apparent is that you can use a lot more uniforms in shaders using uniform buffer objects. OpenGL has a limit to how much uniform data it can handle which can be queried with <var>GL_MAX_VERTEX_UNIFORM_COMPONENTS</var>. When using uniform buffer objects, this limit is much higher. So whenever you reach a maximum number of uniforms (when doing skeletal animation for example) there's always uniform buffer objects.
    946 </p>       
    947 
    948     </div>
    949     
    950 	</main>
    951 </body>
    952 </html>