Roi Atalla avatar Roi Atalla committed bd21332

Example 13.2 fully ported.

Comments (0)

Files changed (14)

.idea/workspace.xml

 <?xml version="1.0" encoding="UTF-8"?>
 <project version="4">
   <component name="ChangeListManager">
-    <list default="true" id="3bd3582b-975a-4915-888d-8e2c52d85938" name="Default" comment="Example 12.3 fully ported.">
-      <change type="NEW" beforePath="" afterPath="$PROJECT_DIR$/src/com/ra4king/opengl/arcsynthesis/gl33/chapter13/example1/Example13_1.java" />
-      <change type="NEW" beforePath="" afterPath="$PROJECT_DIR$/src/com/ra4king/opengl/arcsynthesis/gl33/chapter13/example2/Example13_2.java" />
-      <change type="NEW" beforePath="" afterPath="$PROJECT_DIR$/src/com/ra4king/opengl/util/UniformBlockArray.java" />
-      <change type="NEW" beforePath="" afterPath="$PROJECT_DIR$/src/com/ra4king/opengl/arcsynthesis/gl33/chapter13/example1/example13.1.BasicImpostor.frag" />
-      <change type="NEW" beforePath="" afterPath="$PROJECT_DIR$/src/com/ra4king/opengl/arcsynthesis/gl33/chapter13/example1/example13.1.BasicImpostor.vert" />
-      <change type="NEW" beforePath="" afterPath="$PROJECT_DIR$/src/com/ra4king/opengl/arcsynthesis/gl33/chapter13/example1/example13.1.DepthImpostor.frag" />
-      <change type="NEW" beforePath="" afterPath="$PROJECT_DIR$/src/com/ra4king/opengl/arcsynthesis/gl33/chapter13/example1/example13.1.DepthImpostor.vert" />
-      <change type="NEW" beforePath="" afterPath="$PROJECT_DIR$/src/com/ra4king/opengl/arcsynthesis/gl33/chapter13/example1/example13.1.LargePlane.xml" />
-      <change type="NEW" beforePath="" afterPath="$PROJECT_DIR$/src/com/ra4king/opengl/arcsynthesis/gl33/chapter13/example1/example13.1.Lighting.frag" />
-      <change type="NEW" beforePath="" afterPath="$PROJECT_DIR$/src/com/ra4king/opengl/arcsynthesis/gl33/chapter13/example1/example13.1.PN.vert" />
-      <change type="NEW" beforePath="" afterPath="$PROJECT_DIR$/src/com/ra4king/opengl/arcsynthesis/gl33/chapter13/example1/example13.1.PerspImpostor.frag" />
-      <change type="NEW" beforePath="" afterPath="$PROJECT_DIR$/src/com/ra4king/opengl/arcsynthesis/gl33/chapter13/example1/example13.1.PerspImpostor.vert" />
-      <change type="NEW" beforePath="" afterPath="$PROJECT_DIR$/src/com/ra4king/opengl/arcsynthesis/gl33/chapter13/example1/example13.1.UnitCube.xml" />
-      <change type="NEW" beforePath="" afterPath="$PROJECT_DIR$/src/com/ra4king/opengl/arcsynthesis/gl33/chapter13/example1/example13.1.UnitSphere.xml" />
-      <change type="NEW" beforePath="" afterPath="$PROJECT_DIR$/src/com/ra4king/opengl/arcsynthesis/gl33/chapter13/example1/example13.1.Unlit.frag" />
-      <change type="NEW" beforePath="" afterPath="$PROJECT_DIR$/src/com/ra4king/opengl/arcsynthesis/gl33/chapter13/example1/example13.1.Unlit.vert" />
-      <change type="DELETED" beforePath="E:\Roi Atalla\Documents\Programming Files\Java Files\Personal Projects\OpenGL\src\com\ra4king\opengl\superbible\README.md" afterPath="" />
-      <change type="DELETED" beforePath="E:\Roi Atalla\Documents\Programming Files\Java Files\Personal Projects\OpenGL\src\com\ra4king\opengl\arcsynthesis\README.md" afterPath="" />
-      <change type="DELETED" beforePath="E:\Roi Atalla\Documents\Programming Files\Java Files\Personal Projects\OpenGL\src\com\ra4king\opengl\redbook\README.md" afterPath="" />
-      <change type="DELETED" beforePath="E:\Roi Atalla\Documents\Programming Files\Java Files\Personal Projects\OpenGL\src\com\ra4king\opengl\util\README.md" afterPath="" />
-      <change type="MODIFICATION" beforePath="$PROJECT_DIR$/src/com/ra4king/opengl/arcsynthesis/gl33/chapter12/LightManager.java" afterPath="$PROJECT_DIR$/src/com/ra4king/opengl/arcsynthesis/gl33/chapter12/LightManager.java" />
-      <change type="MODIFICATION" beforePath="$PROJECT_DIR$/src/com/ra4king/opengl/util/math/Matrix4.java" afterPath="$PROJECT_DIR$/src/com/ra4king/opengl/util/math/Matrix4.java" />
-      <change type="MODIFICATION" beforePath="$PROJECT_DIR$/src/com/ra4king/opengl/util/MousePoles.java" afterPath="$PROJECT_DIR$/src/com/ra4king/opengl/util/MousePoles.java" />
+    <list default="true" id="3bd3582b-975a-4915-888d-8e2c52d85938" name="Default" comment="Example 13.1 fully ported.">
+      <change type="NEW" beforePath="" afterPath="$PROJECT_DIR$/src/com/ra4king/opengl/arcsynthesis/gl33/chapter13/example2/example13.2.GeomImpostor.frag" />
+      <change type="NEW" beforePath="" afterPath="$PROJECT_DIR$/src/com/ra4king/opengl/arcsynthesis/gl33/chapter13/example2/example13.2.GeomImpostor.geom" />
+      <change type="NEW" beforePath="" afterPath="$PROJECT_DIR$/src/com/ra4king/opengl/arcsynthesis/gl33/chapter13/example2/example13.2.GeomImpostor.vert" />
+      <change type="NEW" beforePath="" afterPath="$PROJECT_DIR$/src/com/ra4king/opengl/arcsynthesis/gl33/chapter13/example2/example13.2.LargePlane.xml" />
+      <change type="NEW" beforePath="" afterPath="$PROJECT_DIR$/src/com/ra4king/opengl/arcsynthesis/gl33/chapter13/example2/example13.2.Lighting.frag" />
+      <change type="NEW" beforePath="" afterPath="$PROJECT_DIR$/src/com/ra4king/opengl/arcsynthesis/gl33/chapter13/example2/example13.2.PN.vert" />
+      <change type="NEW" beforePath="" afterPath="$PROJECT_DIR$/src/com/ra4king/opengl/arcsynthesis/gl33/chapter13/example2/example13.2.UnitCube.xml" />
+      <change type="NEW" beforePath="" afterPath="$PROJECT_DIR$/src/com/ra4king/opengl/arcsynthesis/gl33/chapter13/example2/example13.2.UnitSphere.xml" />
+      <change type="NEW" beforePath="" afterPath="$PROJECT_DIR$/src/com/ra4king/opengl/arcsynthesis/gl33/chapter13/example2/example13.2.Unlit.frag" />
+      <change type="NEW" beforePath="" afterPath="$PROJECT_DIR$/src/com/ra4king/opengl/arcsynthesis/gl33/chapter13/example2/example13.2.Unlit.vert" />
+      <change type="MODIFICATION" beforePath="$PROJECT_DIR$/src/com/ra4king/opengl/arcsynthesis/gl33/chapter13/example1/Example13_1.java" afterPath="$PROJECT_DIR$/src/com/ra4king/opengl/arcsynthesis/gl33/chapter13/example1/Example13_1.java" />
+      <change type="MODIFICATION" beforePath="$PROJECT_DIR$/src/com/ra4king/opengl/arcsynthesis/gl33/chapter13/example2/Example13_2.java" afterPath="$PROJECT_DIR$/src/com/ra4king/opengl/arcsynthesis/gl33/chapter13/example2/Example13_2.java" />
+      <change type="MODIFICATION" beforePath="$PROJECT_DIR$/src/com/ra4king/opengl/util/ShaderProgram.java" afterPath="$PROJECT_DIR$/src/com/ra4king/opengl/util/ShaderProgram.java" />
       <change type="MODIFICATION" beforePath="$PROJECT_DIR$/.idea/workspace.xml" afterPath="$PROJECT_DIR$/.idea/workspace.xml" />
     </list>
     <ignored path="OpenGL.iws" />
     <ignored path=".idea/workspace.xml" />
-    <file path="/a.java" changelist="3bd3582b-975a-4915-888d-8e2c52d85938" time="1362444430804" ignored="false" />
+    <file path="/a.java" changelist="3bd3582b-975a-4915-888d-8e2c52d85938" time="1362744778367" ignored="false" />
     <file path="/fragment.java" changelist="3bd3582b-975a-4915-888d-8e2c52d85938" time="1362456584258" ignored="false" />
     <file path="/a.xml" changelist="3bd3582b-975a-4915-888d-8e2c52d85938" time="1361850040520" ignored="false" />
     <file path="/a.html" changelist="3bd3582b-975a-4915-888d-8e2c52d85938" time="1361850041808" ignored="false" />
     <file path="/a.groovy" changelist="3bd3582b-975a-4915-888d-8e2c52d85938" time="1361850042481" ignored="false" />
-    <file path="/Dummy.txt" changelist="3bd3582b-975a-4915-888d-8e2c52d85938" time="1362463188818" ignored="false" />
+    <file path="/Dummy.txt" changelist="3bd3582b-975a-4915-888d-8e2c52d85938" time="1362803203510" ignored="false" />
     <file path="/Example12_1.java" changelist="3bd3582b-975a-4915-888d-8e2c52d85938" time="1362027020824" ignored="false" />
     <file path="/example12.1.DiffuseSpecular.frag" changelist="3bd3582b-975a-4915-888d-8e2c52d85938" time="1361702005810" ignored="false" />
     <file path="/LightManager.java" changelist="3bd3582b-975a-4915-888d-8e2c52d85938" time="1362461124226" ignored="false" />
-    <file path="/sample.java" changelist="3bd3582b-975a-4915-888d-8e2c52d85938" time="1362443659696" ignored="false" />
+    <file path="/sample.java" changelist="3bd3582b-975a-4915-888d-8e2c52d85938" time="1362744777504" ignored="false" />
     <file path="/Scene.java" changelist="3bd3582b-975a-4915-888d-8e2c52d85938" time="1362029076804" ignored="false" />
     <file path="$PROJECT_DIR$/bin/com/ra4king/opengl/arcsynthesis/gl33/chapter8/example1/example8.1.Ship.xml" changelist="3bd3582b-975a-4915-888d-8e2c52d85938" time="1361777249769" ignored="false" />
     <file path="$PROJECT_DIR$/bin/com/ra4king/opengl/arcsynthesis/gl33/chapter8/example2/example8.2.Ship.xml" changelist="3bd3582b-975a-4915-888d-8e2c52d85938" time="1361777249770" ignored="false" />
     <file path="/example12.3.DiffuseOnlyMtlGamma.frag" changelist="3bd3582b-975a-4915-888d-8e2c52d85938" time="1362455044354" ignored="false" />
     <file path="/example12.3.DiffuseSpecularGamma.frag" changelist="3bd3582b-975a-4915-888d-8e2c52d85938" time="1362455100183" ignored="false" />
     <file path="/example12.3.DiffuseSpecularMtlGamma.frag" changelist="3bd3582b-975a-4915-888d-8e2c52d85938" time="1362455113040" ignored="false" />
-    <file path="/Example13_1.java" changelist="3bd3582b-975a-4915-888d-8e2c52d85938" time="1362630395179" ignored="false" />
+    <file path="/Example13_1.java" changelist="3bd3582b-975a-4915-888d-8e2c52d85938" time="1362743787489" ignored="false" />
     <file path="/UniformBlockArray.java" changelist="3bd3582b-975a-4915-888d-8e2c52d85938" time="1362460808991" ignored="false" />
     <file path="$PROJECT_DIR$/src/com/ra4king/opengl/test/Test.java" changelist="3bd3582b-975a-4915-888d-8e2c52d85938" time="1362463155785" ignored="false" />
     <file path="$PROJECT_DIR$/src/com/ra4king/opengl/superbible/osb5/chapter2/example1/Example2_1.java" changelist="3bd3582b-975a-4915-888d-8e2c52d85938" time="1362463155786" ignored="false" />
     <file path="/example13.1.PN.vert" changelist="3bd3582b-975a-4915-888d-8e2c52d85938" time="1362629589022" ignored="false" />
     <file path="/example13.1.Lighting.frag" changelist="3bd3582b-975a-4915-888d-8e2c52d85938" time="1362629642934" ignored="false" />
     <file path="/example13.1.Unlit.frag" changelist="3bd3582b-975a-4915-888d-8e2c52d85938" time="1362629803134" ignored="false" />
+    <file path="/ShaderProgram.java" changelist="3bd3582b-975a-4915-888d-8e2c52d85938" time="1362634626807" ignored="false" />
+    <file path="/Example13_2.java" changelist="3bd3582b-975a-4915-888d-8e2c52d85938" time="1362782884856" ignored="false" />
+    <file path="/example13.2.GeomImpostor.vert" changelist="3bd3582b-975a-4915-888d-8e2c52d85938" time="1362745735663" ignored="false" />
+    <file path="/example13.2.GeomImpostor.frag" changelist="3bd3582b-975a-4915-888d-8e2c52d85938" time="1362783613195" ignored="false" />
+    <file path="/example13.2.GeomImpostor.geom" changelist="3bd3582b-975a-4915-888d-8e2c52d85938" time="1362788035299" ignored="false" />
     <option name="TRACKING_ENABLED" value="true" />
     <option name="SHOW_DIALOG" value="false" />
     <option name="HIGHLIGHT_CONFLICTS" value="true" />
     <disable_hints />
   </component>
   <component name="DebuggerManager">
-    <line_breakpoints default_suspend_policy="SuspendAll" default_condition_enabled="true">
-      <breakpoint url="file://$PROJECT_DIR$/src/com/ra4king/opengl/util/MousePoles.java" line="385" class="com.ra4king.opengl.util.MousePoles.ViewPole" package="com.ra4king.opengl.util">
-        <option name="ENABLED" value="true" />
-        <option name="LOG_ENABLED" value="false" />
-        <option name="LOG_EXPRESSION_ENABLED" value="false" />
-        <option name="SUSPEND_POLICY" value="SuspendAll" />
-        <option name="SUSPEND" value="true" />
-        <option name="COUNT_FILTER_ENABLED" value="false" />
-        <option name="COUNT_FILTER" value="0" />
-        <option name="CONDITION_ENABLED" value="true" />
-        <option name="CLASS_FILTERS_ENABLED" value="false" />
-        <option name="INSTANCE_FILTERS_ENABLED" value="false" />
-        <option name="CONDITION" value="" />
-        <option name="LOG_MESSAGE" value="" />
-      </breakpoint>
-    </line_breakpoints>
+    <line_breakpoints default_suspend_policy="SuspendAll" default_condition_enabled="true" />
     <breakpoint_any default_suspend_policy="SuspendAll" default_condition_enabled="true">
       <breakpoint>
         <option name="NOTIFY_CAUGHT" value="true" />
   <component name="IdeDocumentHistory">
     <option name="changedFiles">
       <list>
-        <option value="$PROJECT_DIR$/src/com/ra4king/opengl/arcsynthesis/gl33/chapter13/example1/example13.1.LargePlane.xml" />
-        <option value="$PROJECT_DIR$/src/com/ra4king/opengl/arcsynthesis/gl33/chapter13/example1/example13.1.UnitCube.xml" />
-        <option value="$PROJECT_DIR$/src/com/ra4king/opengl/arcsynthesis/gl33/chapter13/example1/example13.1.UnitSphere.xml" />
-        <option value="$PROJECT_DIR$/src/com/ra4king/opengl/arcsynthesis/gl33/chapter13/example1/example13.1.DepthImpostor.vert" />
-        <option value="$PROJECT_DIR$/src/com/ra4king/opengl/arcsynthesis/gl33/chapter13/example1/example13.1.BasicImpostor.vert" />
         <option value="$PROJECT_DIR$/src/com/ra4king/opengl/arcsynthesis/gl33/chapter13/example1/example13.1.DepthImpostor.frag" />
         <option value="$PROJECT_DIR$/src/com/ra4king/opengl/arcsynthesis/gl33/chapter13/example1/example13.1.PerspImpostor.vert" />
         <option value="$PROJECT_DIR$/src/com/ra4king/opengl/arcsynthesis/gl33/chapter13/example1/example13.1.PerspImpostor.frag" />
         <option value="$PROJECT_DIR$/src/com/ra4king/opengl/arcsynthesis/gl33/chapter13/example1/example13.1.Unlit.frag" />
         <option value="$PROJECT_DIR$/src/com/ra4king/opengl/util/math/Matrix4.java" />
         <option value="$PROJECT_DIR$/src/com/ra4king/opengl/util/MousePoles.java" />
+        <option value="$PROJECT_DIR$/src/com/ra4king/opengl/util/ShaderProgram.java" />
         <option value="$PROJECT_DIR$/src/com/ra4king/opengl/arcsynthesis/gl33/chapter13/example1/Example13_1.java" />
+        <option value="$PROJECT_DIR$/src/com/ra4king/opengl/arcsynthesis/gl33/chapter13/example2/example13.2.GeomImpostor.vert" />
+        <option value="$PROJECT_DIR$/src/com/ra4king/opengl/arcsynthesis/gl33/chapter13/example2/Example13_2.java" />
+        <option value="$PROJECT_DIR$/src/com/ra4king/opengl/arcsynthesis/gl33/chapter13/example2/example13.2.GeomImpostor.geom" />
+        <option value="$PROJECT_DIR$/src/com/ra4king/opengl/arcsynthesis/gl33/chapter13/example2/example13.2.GeomImpostor.frag" />
       </list>
     </option>
   </component>
       <sortByType />
     </navigator>
     <panes>
+      <pane id="PackagesPane">
+        <subPane />
+      </pane>
       <pane id="ProjectPane">
         <subPane>
           <PATH>
               <option name="myItemType" value="com.intellij.ide.projectView.impl.nodes.PsiDirectoryNode" />
             </PATH_ELEMENT>
             <PATH_ELEMENT>
-              <option name="myItemId" value="util" />
-              <option name="myItemType" value="com.intellij.ide.projectView.impl.nodes.PsiDirectoryNode" />
-            </PATH_ELEMENT>
-          </PATH>
-          <PATH>
-            <PATH_ELEMENT>
-              <option name="myItemId" value="OpenGL" />
-              <option name="myItemType" value="com.intellij.ide.projectView.impl.nodes.ProjectViewProjectNode" />
-            </PATH_ELEMENT>
-            <PATH_ELEMENT>
-              <option name="myItemId" value="OpenGL" />
-              <option name="myItemType" value="com.intellij.ide.projectView.impl.nodes.PsiDirectoryNode" />
-            </PATH_ELEMENT>
-            <PATH_ELEMENT>
-              <option name="myItemId" value="src" />
-              <option name="myItemType" value="com.intellij.ide.projectView.impl.nodes.PsiDirectoryNode" />
-            </PATH_ELEMENT>
-            <PATH_ELEMENT>
-              <option name="myItemId" value="opengl" />
-              <option name="myItemType" value="com.intellij.ide.projectView.impl.nodes.PsiDirectoryNode" />
-            </PATH_ELEMENT>
-            <PATH_ELEMENT>
               <option name="myItemId" value="gl33" />
               <option name="myItemType" value="com.intellij.ide.projectView.impl.nodes.PsiDirectoryNode" />
             </PATH_ELEMENT>
               <option name="myItemId" value="gl33" />
               <option name="myItemType" value="com.intellij.ide.projectView.impl.nodes.PsiDirectoryNode" />
             </PATH_ELEMENT>
-            <PATH_ELEMENT>
-              <option name="myItemId" value="chapter13" />
-              <option name="myItemType" value="com.intellij.ide.projectView.impl.nodes.PsiDirectoryNode" />
-            </PATH_ELEMENT>
-            <PATH_ELEMENT>
-              <option name="myItemId" value="example1" />
-              <option name="myItemType" value="com.intellij.ide.projectView.impl.nodes.PsiDirectoryNode" />
-            </PATH_ELEMENT>
           </PATH>
           <PATH>
             <PATH_ELEMENT>
               <option name="myItemType" value="com.intellij.ide.projectView.impl.nodes.PsiDirectoryNode" />
             </PATH_ELEMENT>
             <PATH_ELEMENT>
-              <option name="myItemId" value="src" />
-              <option name="myItemType" value="com.intellij.ide.projectView.impl.nodes.PsiDirectoryNode" />
-            </PATH_ELEMENT>
-            <PATH_ELEMENT>
-              <option name="myItemId" value="opengl" />
-              <option name="myItemType" value="com.intellij.ide.projectView.impl.nodes.PsiDirectoryNode" />
-            </PATH_ELEMENT>
-            <PATH_ELEMENT>
-              <option name="myItemId" value="gl33" />
+              <option name="myItemId" value=".idea" />
               <option name="myItemType" value="com.intellij.ide.projectView.impl.nodes.PsiDirectoryNode" />
             </PATH_ELEMENT>
           </PATH>
         </subPane>
       </pane>
       <pane id="Scope" />
-      <pane id="PackagesPane">
-        <subPane />
-      </pane>
     </panes>
   </component>
   <component name="PropertiesComponent">
     <property name="FileHistory.org.zmlx.hg4idea.provider.HgHistoryProvider_flatWidth2" value="289" />
     <property name="FileHistory.org.zmlx.hg4idea.provider.HgHistoryProvider_flatWidth1" value="289" />
     <property name="FileHistory.org.zmlx.hg4idea.provider.HgHistoryProvider_flatWidth0" value="289" />
-    <property name="options.lastSelected" value="reference.settingsdialog.IDE.editor.colors.Java" />
+    <property name="options.lastSelected" value="project.propVCSSupport.Ignored.Files" />
     <property name="FileHistory.org.zmlx.hg4idea.provider.HgHistoryProvider_flatOrder1" value="1" />
     <property name="FileHistory.org.zmlx.hg4idea.provider.HgHistoryProvider_flatOrder0" value="0" />
     <property name="project.structure.side.proportion" value="0.2" />
       <recent name="com.ra4king.opengl.arcsynthesis.gl33.chapter12.example2" />
     </key>
     <key name="CopyFile.RECENT_KEYS">
+      <recent name="E:\Roi Atalla\Documents\Programming Files\Java Files\Personal Projects\OpenGL\src\com\ra4king\opengl\arcsynthesis\gl33\chapter13\example2" />
       <recent name="E:\Roi Atalla\Documents\Programming Files\Java Files\Personal Projects\OpenGL\src\com\ra4king\opengl\arcsynthesis\gl33\chapter13\example1" />
       <recent name="E:\Roi Atalla\Documents\Programming Files\Java Files\Personal Projects\OpenGL\src\com\ra4king\opengl\arcsynthesis\gl33\chapter12\example3" />
       <recent name="E:\Roi Atalla\Documents\Programming Files\Java Files\Personal Projects\OpenGL\src\com\ra4king\opengl\arcsynthesis\gl33\chapter12\example2" />
       <recent name="E:\Roi Atalla\Documents\Programming Files\Java Files\Personal Projects\OpenGL\files\natives" />
-      <recent name="E:\Roi Atalla\Documents\Programming Files\Java Files\Personal Projects\OpenGL\files" />
     </key>
   </component>
-  <component name="RunManager" selected="Application.Example13_1">
+  <component name="RunManager" selected="Application.Example13_2">
     <configuration default="false" name="Example12_2" type="Application" factoryName="Application" temporary="true">
       <option name="MAIN_CLASS_NAME" value="com.ra4king.opengl.arcsynthesis.gl33.chapter12.example2.Example12_2" />
       <option name="VM_PARAMETERS" value="-Djava.library.path=files/natives/" />
       <ConfigurationWrapper RunnerId="Run" />
       <method />
     </configuration>
+    <configuration default="false" name="Example13_2" type="Application" factoryName="Application" temporary="true">
+      <option name="MAIN_CLASS_NAME" value="com.ra4king.opengl.arcsynthesis.gl33.chapter13.example2.Example13_2" />
+      <option name="VM_PARAMETERS" value="-Djava.library.path=files/natives/" />
+      <option name="PROGRAM_PARAMETERS" value="" />
+      <option name="WORKING_DIRECTORY" value="file://$PROJECT_DIR$" />
+      <option name="ALTERNATIVE_JRE_PATH_ENABLED" value="false" />
+      <option name="ALTERNATIVE_JRE_PATH" value="" />
+      <option name="ENABLE_SWING_INSPECTOR" value="false" />
+      <option name="ENV_VARIABLES" />
+      <option name="PASS_PARENT_ENVS" value="true" />
+      <module name="OpenGL" />
+      <envs />
+      <RunnerSettings RunnerId="Run" />
+      <ConfigurationWrapper RunnerId="Run" />
+      <method />
+    </configuration>
     <configuration default="true" type="#org.jetbrains.idea.devkit.run.PluginConfigurationType" factoryName="Plugin">
       <module name="" />
       <option name="VM_PARAMETERS" value="-Xmx512m -Xms256m -XX:MaxPermSize=250m" />
       <option name="CLEAR_LOGCAT" value="false" />
       <method />
     </configuration>
-    <list size="4">
+    <list size="5">
       <item index="0" class="java.lang.String" itemvalue="Application.Example12_2" />
       <item index="1" class="java.lang.String" itemvalue="Application.Example12_1" />
       <item index="2" class="java.lang.String" itemvalue="Application.Example12_3" />
       <item index="3" class="java.lang.String" itemvalue="Application.Example13_1" />
+      <item index="4" class="java.lang.String" itemvalue="Application.Example13_2" />
     </list>
     <recent_temporary>
-      <list size="4">
-        <item index="0" class="java.lang.String" itemvalue="Application.Example13_1" />
+      <list size="5">
+        <item index="0" class="java.lang.String" itemvalue="Application.Example13_2" />
         <item index="1" class="java.lang.String" itemvalue="Application.Example12_3" />
-        <item index="2" class="java.lang.String" itemvalue="Application.Example12_2" />
-        <item index="3" class="java.lang.String" itemvalue="Application.Example12_1" />
+        <item index="2" class="java.lang.String" itemvalue="Application.Example13_1" />
+        <item index="3" class="java.lang.String" itemvalue="Application.Example12_2" />
+        <item index="4" class="java.lang.String" itemvalue="Application.Example12_1" />
       </list>
     </recent_temporary>
     <configuration name="&lt;template&gt;" type="WebApp" default="true" selected="false">
       <created>1362455413134</created>
       <updated>1362455413134</updated>
     </task>
-    <option name="localTasksCounter" value="10" />
+    <task id="LOCAL-00010" summary="Example 13.1 fully ported.">
+      <created>1362630633990</created>
+      <updated>1362630633990</updated>
+    </task>
+    <option name="localTasksCounter" value="11" />
     <servers />
   </component>
   <component name="TodoView" selected-index="0">
       <window_info id="Changes" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" weight="0.32942432" sideWeight="0.5" order="7" side_tool="false" content_ui="tabs" />
       <window_info id="JetGradle" active="false" anchor="right" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" weight="0.32977587" sideWeight="0.5" order="3" side_tool="false" content_ui="tabs" />
       <window_info id="Palette" active="false" anchor="right" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" weight="0.33" sideWeight="0.5" order="3" side_tool="false" content_ui="tabs" />
-      <window_info id="Find" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" weight="0.21641791" sideWeight="0.5" order="1" side_tool="false" content_ui="tabs" />
       <window_info id="Ant Build" active="false" anchor="right" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" weight="0.2497332" sideWeight="0.5" order="1" side_tool="false" content_ui="tabs" />
       <window_info id="Debug" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" weight="0.081023455" sideWeight="0.5" order="3" side_tool="false" content_ui="tabs" />
       <window_info id="Event Log" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" weight="0.32905984" sideWeight="0.5" order="8" side_tool="true" content_ui="tabs" />
       <window_info id="Favorites" active="false" anchor="left" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" weight="0.18366013" sideWeight="0.14915694" order="2" side_tool="true" content_ui="tabs" />
       <window_info id="Version Control" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" weight="0.24413647" sideWeight="0.5" order="10" side_tool="false" content_ui="tabs" />
-      <window_info id="Messages" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" weight="0.3304904" sideWeight="0.5" order="9" side_tool="false" content_ui="tabs" />
+      <window_info id="Messages" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" weight="0.32978722" sideWeight="0.5" order="9" side_tool="false" content_ui="tabs" />
       <window_info id="TODO" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" weight="0.3283582" sideWeight="0.5" order="6" side_tool="false" content_ui="tabs" />
       <window_info id="Structure" active="false" anchor="left" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" weight="0.18366013" sideWeight="0.17250325" order="1" side_tool="true" content_ui="tabs" />
       <window_info id="Maven Projects" active="false" anchor="right" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" weight="0.32977587" sideWeight="0.5" order="3" side_tool="false" content_ui="tabs" />
       <window_info id="Commander" active="false" anchor="right" auto_hide="false" internal_type="SLIDING" type="SLIDING" visible="false" weight="0.4" sideWeight="0.5" order="0" side_tool="false" content_ui="tabs" />
-      <window_info id="Project" active="true" anchor="left" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="true" weight="0.21184632" sideWeight="0.96588486" order="0" side_tool="true" content_ui="combo" x="2394" y="136" width="397" height="768" />
-      <window_info id="Run" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="true" weight="0.03411514" sideWeight="0.9898039" order="2" side_tool="false" content_ui="tabs" />
+      <window_info id="Project" active="true" anchor="left" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="true" weight="0.21558164" sideWeight="0.7356077" order="0" side_tool="true" content_ui="combo" x="2394" y="136" width="397" height="768" />
+      <window_info id="Run" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="true" weight="0.26439232" sideWeight="0.9898039" order="2" side_tool="false" content_ui="tabs" />
       <window_info id="Documentation" active="true" anchor="right" auto_hide="false" internal_type="DOCKED" type="FLOATING" visible="true" weight="0.33" sideWeight="0.5" order="3" side_tool="false" content_ui="tabs" x="2005" y="109" width="1736" height="896" />
       <window_info id="Cvs" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" weight="0.25" sideWeight="0.5" order="4" side_tool="false" content_ui="tabs" />
       <window_info id="Message" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" weight="0.33" sideWeight="0.5" order="0" side_tool="false" content_ui="tabs" />
+      <window_info id="Find" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" weight="0.21641791" sideWeight="0.5" order="1" side_tool="false" content_ui="tabs" />
       <window_info id="Hierarchy" active="false" anchor="right" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" weight="0.25" sideWeight="0.5" order="2" side_tool="false" content_ui="combo" />
       <window_info id="Inspection" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" weight="0.39978677" sideWeight="0.5" order="5" side_tool="false" content_ui="tabs" />
     </layout>
     <option name="MAXIMUM_HISTORY_ROWS" value="1000" />
     <option name="FORCE_NON_EMPTY_COMMENT" value="false" />
     <option name="CLEAR_INITIAL_COMMIT_MESSAGE" value="false" />
-    <option name="LAST_COMMIT_MESSAGE" value="Example 12.3 fully ported." />
+    <option name="LAST_COMMIT_MESSAGE" value="Example 13.1 fully ported." />
     <option name="MAKE_NEW_CHANGELIST_ACTIVE" value="false" />
     <option name="OPTIMIZE_IMPORTS_BEFORE_PROJECT_COMMIT" value="false" />
     <option name="CHECK_FILES_UP_TO_DATE_BEFORE_COMMIT" value="false" />
     <MESSAGE value="*HUGE* error in my Matrix4.toQuaternion class that caused  buggy 3D movement in Example12.1. Also, completely reformat with Eclipse Formatter plugin for IDEA." />
     <MESSAGE value="Example 12.2 fully ported." />
     <MESSAGE value="Example 12.3 fully ported." />
+    <MESSAGE value="Example 13.1 fully ported." />
   </component>
   <component name="XDebuggerManager">
     <breakpoint-manager>
       </breakpoints-dialog>
     </breakpoint-manager>
   </component>
+  <component name="XSLT-Support.FileAssociations.UIState">
+    <PATH>
+      <PATH_ELEMENT>
+        <option name="myItemId" value="OpenGL" />
+        <option name="myItemType" value="com.intellij.ide.projectView.impl.nodes.ProjectViewProjectNode" />
+      </PATH_ELEMENT>
+      <PATH_ELEMENT>
+        <option name="myItemId" value="OpenGL" />
+        <option name="myItemType" value="com.intellij.ide.projectView.impl.nodes.PsiDirectoryNode" />
+      </PATH_ELEMENT>
+    </PATH>
+  </component>
   <component name="antWorkspaceConfiguration">
     <option name="IS_AUTOSCROLL_TO_SOURCE" value="false" />
     <option name="FILTER_TARGETS" value="false" />
   </component>
   <component name="editorHistoryManager">
-    <entry file="file://$PROJECT_DIR$/src/com/ra4king/opengl/arcsynthesis/gl33/chapter13/example1/example13.1.UnitCube.xml">
+    <entry file="file://$PROJECT_DIR$/src/com/ra4king/opengl/arcsynthesis/gl33/chapter13/example2/example13.2.GeomImpostor.geom">
       <provider selected="true" editor-type-id="text-editor">
-        <state line="113" column="0" selection-start="1719" selection-end="1719" vertical-scroll-proportion="0.9177632">
-          <folding />
-        </state>
-      </provider>
-    </entry>
-    <entry file="file://$PROJECT_DIR$/src/com/ra4king/opengl/arcsynthesis/gl33/chapter13/example1/example13.1.UnitSphere.xml">
-      <provider selected="true" editor-type-id="text-editor">
-        <state line="282" column="0" selection-start="10528" selection-end="10528" vertical-scroll-proportion="0.9013158">
-          <folding />
-        </state>
-      </provider>
-    </entry>
-    <entry file="file://$PROJECT_DIR$/src/com/ra4king/opengl/arcsynthesis/gl33/chapter13/example1/example13.1.BasicImpostor.vert">
-      <provider selected="true" editor-type-id="text-editor">
-        <state line="42" column="0" selection-start="753" selection-end="753" vertical-scroll-proportion="0.69078946">
-          <folding />
-        </state>
-      </provider>
-    </entry>
-    <entry file="file://$PROJECT_DIR$/src/com/ra4king/opengl/arcsynthesis/gl33/chapter13/example1/example13.1.DepthImpostor.vert">
-      <provider selected="true" editor-type-id="text-editor">
-        <state line="44" column="0" selection-start="878" selection-end="878" vertical-scroll-proportion="0.7236842">
-          <folding />
-        </state>
-      </provider>
-    </entry>
-    <entry file="file://$PROJECT_DIR$/src/com/ra4king/opengl/arcsynthesis/gl33/chapter13/example1/example13.1.PerspImpostor.vert">
-      <provider selected="true" editor-type-id="text-editor">
-        <state line="44" column="0" selection-start="861" selection-end="861" vertical-scroll-proportion="0.7236842">
-          <folding />
-        </state>
-      </provider>
-    </entry>
-    <entry file="file://$PROJECT_DIR$/src/com/ra4king/opengl/arcsynthesis/gl33/chapter13/example1/example13.1.PN.vert">
-      <provider selected="true" editor-type-id="text-editor">
-        <state line="26" column="0" selection-start="551" selection-end="551" vertical-scroll-proportion="0.4276316">
-          <folding />
-        </state>
-      </provider>
-    </entry>
-    <entry file="file://$PROJECT_DIR$/src/com/ra4king/opengl/arcsynthesis/gl33/chapter13/example1/example13.1.Lighting.frag">
-      <provider selected="true" editor-type-id="text-editor">
-        <state line="76" column="0" selection-start="1949" selection-end="1949" vertical-scroll-proportion="1.25">
-          <folding />
-        </state>
-      </provider>
-    </entry>
-    <entry file="file://$PROJECT_DIR$/src/com/ra4king/opengl/arcsynthesis/gl33/chapter13/example1/example13.1.Unlit.vert">
-      <provider selected="true" editor-type-id="text-editor">
-        <state line="17" column="0" selection-start="260" selection-end="260" vertical-scroll-proportion="0.27960527">
-          <folding />
-        </state>
-      </provider>
-    </entry>
-    <entry file="file://$PROJECT_DIR$/src/com/ra4king/opengl/arcsynthesis/gl33/chapter13/example1/example13.1.BasicImpostor.frag">
-      <provider selected="true" editor-type-id="text-editor">
-        <state line="82" column="6" selection-start="2035" selection-end="2035" vertical-scroll-proportion="0.29438543">
-          <folding />
-        </state>
-      </provider>
-    </entry>
-    <entry file="file://$PROJECT_DIR$/src/com/ra4king/opengl/arcsynthesis/gl33/chapter13/example1/example13.1.Unlit.frag">
-      <provider selected="true" editor-type-id="text-editor">
-        <state line="3" column="0" selection-start="40" selection-end="40" vertical-scroll-proportion="0.06828528">
-          <folding />
-        </state>
-      </provider>
-    </entry>
-    <entry file="file://$PROJECT_DIR$/src/com/ra4king/opengl/util/math/MatrixStack.java">
-      <provider selected="true" editor-type-id="text-editor">
-        <state line="13" column="19" selection-start="265" selection-end="265" vertical-scroll-proportion="0.2215909">
+        <state line="16" column="0" selection-start="223" selection-end="223" vertical-scroll-proportion="0.0">
           <folding />
         </state>
       </provider>
     </entry>
     <entry file="file://$PROJECT_DIR$/src/com/ra4king/opengl/util/math/Matrix4.java">
       <provider selected="true" editor-type-id="text-editor">
-        <state line="190" column="4" selection-start="4280" selection-end="4280" vertical-scroll-proportion="0.46931818">
-          <folding />
-        </state>
+        <state line="190" column="4" selection-start="4280" selection-end="4280" vertical-scroll-proportion="0.46931818" />
       </provider>
     </entry>
     <entry file="file://$PROJECT_DIR$/src/com/ra4king/opengl/util/MousePoles.java">
       <provider selected="true" editor-type-id="text-editor">
-        <state line="515" column="102" selection-start="13478" selection-end="13478" vertical-scroll-proportion="0.38636363">
-          <folding />
-        </state>
+        <state line="515" column="102" selection-start="13478" selection-end="13478" vertical-scroll-proportion="0.38636363" />
       </provider>
     </entry>
     <entry file="file://$PROJECT_DIR$/src/com/ra4king/opengl/arcsynthesis/gl33/chapter13/example1/example13.1.DepthImpostor.frag">
       <provider selected="true" editor-type-id="text-editor">
-        <state line="89" column="4" selection-start="2346" selection-end="2346" vertical-scroll-proportion="0.33522728">
-          <folding />
-        </state>
+        <state line="89" column="4" selection-start="2346" selection-end="2346" vertical-scroll-proportion="0.33522728" />
       </provider>
     </entry>
     <entry file="file://$PROJECT_DIR$/src/com/ra4king/opengl/arcsynthesis/gl33/chapter13/example1/example13.1.PerspImpostor.frag">
       <provider selected="true" editor-type-id="text-editor">
-        <state line="102" column="0" selection-start="2636" selection-end="2636" vertical-scroll-proportion="0.625">
+        <state line="102" column="0" selection-start="2636" selection-end="2636" vertical-scroll-proportion="0.625" />
+      </provider>
+    </entry>
+    <entry file="file://$PROJECT_DIR$/src/com/ra4king/opengl/util/math/Matrix3.java">
+      <provider selected="true" editor-type-id="text-editor">
+        <state line="7" column="13" selection-start="138" selection-end="138" vertical-scroll-proportion="-0.2556818" />
+      </provider>
+    </entry>
+    <entry file="file://$PROJECT_DIR$/src/com/ra4king/opengl/util/ShaderProgram.java">
+      <provider selected="true" editor-type-id="text-editor">
+        <state line="51" column="8" selection-start="1717" selection-end="1717" vertical-scroll-proportion="0.59090906" />
+      </provider>
+    </entry>
+    <entry file="file://$PROJECT_DIR$/src/com/ra4king/opengl/arcsynthesis/gl33/chapter13/example1/example13.1.LargePlane.xml">
+      <provider selected="true" editor-type-id="text-editor">
+        <state line="0" column="0" selection-start="0" selection-end="0" vertical-scroll-proportion="0.0" />
+      </provider>
+    </entry>
+    <entry file="file://$PROJECT_DIR$/src/com/ra4king/opengl/arcsynthesis/gl33/chapter13/example2/example13.2.Unlit.vert">
+      <provider selected="true" editor-type-id="text-editor">
+        <state line="17" column="0" selection-start="260" selection-end="260" vertical-scroll-proportion="0.27960527" />
+      </provider>
+    </entry>
+    <entry file="file://$PROJECT_DIR$/src/com/ra4king/opengl/GLProgram.java">
+      <provider selected="true" editor-type-id="text-editor">
+        <state line="153" column="0" selection-start="3054" selection-end="3054" vertical-scroll-proportion="0.3323782">
           <folding />
         </state>
       </provider>
     </entry>
     <entry file="file://$PROJECT_DIR$/src/com/ra4king/opengl/arcsynthesis/gl33/chapter13/example1/Example13_1.java">
       <provider selected="true" editor-type-id="text-editor">
-        <state line="251" column="4" selection-start="9518" selection-end="9518" vertical-scroll-proportion="0.8615917">
-          <folding>
-            <element signature="imports" expanded="true" />
-          </folding>
+        <state line="75" column="4" selection-start="2429" selection-end="2429" vertical-scroll-proportion="0.88235295" />
+      </provider>
+    </entry>
+    <entry file="file://$PROJECT_DIR$/src/com/ra4king/opengl/arcsynthesis/gl33/chapter12/example3/Example12_3.java">
+      <provider selected="true" editor-type-id="text-editor">
+        <state line="34" column="13" selection-start="1642" selection-end="1642" vertical-scroll-proportion="0.09049774" />
+      </provider>
+    </entry>
+    <entry file="file://$PROJECT_DIR$/src/com/ra4king/opengl/arcsynthesis/gl33/chapter13/example2/example13.2.GeomImpostor.vert">
+      <provider selected="true" editor-type-id="text-editor">
+        <state line="1" column="0" selection-start="13" selection-end="13" vertical-scroll-proportion="0.022624435" />
+      </provider>
+    </entry>
+    <entry file="file://$PROJECT_DIR$/src/com/ra4king/opengl/arcsynthesis/gl33/chapter13/example2/example13.2.GeomImpostor.frag">
+      <provider selected="true" editor-type-id="text-editor">
+        <state line="1" column="0" selection-start="13" selection-end="13" vertical-scroll-proportion="0.022590362" />
+      </provider>
+    </entry>
+    <entry file="file://$PROJECT_DIR$/src/com/ra4king/opengl/arcsynthesis/gl33/chapter13/example2/example13.2.GeomImpostor.geom">
+      <provider selected="true" editor-type-id="text-editor">
+        <state line="36" column="0" selection-start="767" selection-end="767" vertical-scroll-proportion="0.5256024">
+          <folding />
+        </state>
+      </provider>
+    </entry>
+    <entry file="file://$PROJECT_DIR$/src/com/ra4king/opengl/arcsynthesis/gl33/chapter13/example2/Example13_2.java">
+      <provider selected="true" editor-type-id="text-editor">
+        <state line="369" column="4" selection-start="13789" selection-end="13789" vertical-scroll-proportion="0.022590362">
+          <folding />
         </state>
       </provider>
     </entry>

src/com/ra4king/opengl/arcsynthesis/gl33/chapter13/example1/Example13_1.java

 	private ProgramImposData[] litImpPrograms = new ProgramImposData[Impostors.values().length];
 	private UnlitProgramData unlit;
 	
+	private Mesh planeMesh;
+	private Mesh sphereMesh;
+	private Mesh cubeMesh;
+	
 	private ViewPole viewPole;
 	
 	private Impostors currentImpostor = Impostors.BASIC;
 	
 	private Timer sphereTimer = new Timer(Type.LOOP, 6);
 	
-	private int impostoreVAO;
+	private int impostorVAO;
 	
-	private Mesh planeMesh;
-	private Mesh sphereMesh;
-	private Mesh cubeMesh;
+	private final int materialBlockIndex = 0;
+	private final int lightBlockIndex = 1;
+	private final int projectionBlockIndex = 2;
 	
 	private int materialUniformBuffer;
 	private int lightUniformBuffer;
 	private int projectionUniformBuffer;
 	
 	private int materialBlockOffset;
-	
-	private int materialBlockIndex = 0;
-	private int lightBlockIndex = 1;
-	private int projectionBlockIndex = 2;
-	
+
 	private final float halfLightDistance = 25;
 	private final float lightAttenuation = 1f / (halfLightDistance * halfLightDistance);
 	
 		
 		glBindBuffer(GL_UNIFORM_BUFFER, 0);
 		
-		impostoreVAO = glGenVertexArrays();
+		impostorVAO = glGenVertexArrays();
 		
 		createMaterials();
 	}
 			glUniform3(litImpPrograms[currentImpostor.ordinal()].cameraSpherePosUniform, modelMatrix.getTop().mult(new Vector4(position, 1)).toBuffer());
 			glUniform1f(litImpPrograms[currentImpostor.ordinal()].sphereRadiusUniform, radius);
 			
-			glBindVertexArray(impostoreVAO);
+			glBindVertexArray(impostorVAO);
 			glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
 			glBindVertexArray(0);
 			

src/com/ra4king/opengl/arcsynthesis/gl33/chapter13/example2/Example13_2.java

 package com.ra4king.opengl.arcsynthesis.gl33.chapter13.example2;
 
-public class Example13_2 {}
+import static org.lwjgl.opengl.GL11.*;
+import static org.lwjgl.opengl.GL15.*;
+import static org.lwjgl.opengl.GL20.*;
+import static org.lwjgl.opengl.GL30.*;
+import static org.lwjgl.opengl.GL31.*;
+import static org.lwjgl.opengl.GL32.*;
+
+import java.nio.FloatBuffer;
+import java.util.ArrayList;
+
+import org.lwjgl.BufferUtils;
+import org.lwjgl.input.Keyboard;
+
+import com.ra4king.opengl.GLProgram;
+import com.ra4king.opengl.util.Mesh;
+import com.ra4king.opengl.util.MousePoles.MouseButton;
+import com.ra4king.opengl.util.MousePoles.ViewData;
+import com.ra4king.opengl.util.MousePoles.ViewPole;
+import com.ra4king.opengl.util.MousePoles.ViewScale;
+import com.ra4king.opengl.util.ShaderProgram;
+import com.ra4king.opengl.util.Timer;
+import com.ra4king.opengl.util.Timer.Type;
+import com.ra4king.opengl.util.UniformBlockArray.UniformBlockObject;
+import com.ra4king.opengl.util.Utils;
+import com.ra4king.opengl.util.math.Matrix3;
+import com.ra4king.opengl.util.math.Matrix4;
+import com.ra4king.opengl.util.math.MatrixStack;
+import com.ra4king.opengl.util.math.Quaternion;
+import com.ra4king.opengl.util.math.Vector3;
+import com.ra4king.opengl.util.math.Vector4;
+
+public class Example13_2 extends GLProgram {
+	public static void main(String[] args) {
+		new Example13_2().run(true);
+	}
+	
+	private ProgramMeshData litMeshProgram;
+	private ProgramImposData litImpProgram;
+	private UnlitProgramData unlit;
+	
+	private Mesh planeMesh;
+	private Mesh sphereMesh;
+	private Mesh cubeMesh;
+	
+	private ViewPole viewPole;
+	
+	private Timer sphereTimer = new Timer(Type.LOOP, 6);
+	
+	private int impostorVAO;
+	private int impostorVBO;
+	
+	private final int materialBlockIndex = 0;
+	private final int lightBlockIndex = 1;
+	private final int projectionBlockIndex = 2;
+	
+	private int lightUniformBuffer;
+	private int projectionUniformBuffer;
+	private int materialArrayUniformBuffer;
+	private int materialTerrainUniformBuffer;
+	
+	private final float halfLightDistance = 25;
+	private final float lightAttenuation = 1f / (halfLightDistance * halfLightDistance);
+	
+	private boolean drawCameraPos, drawLights = true;
+	
+	private static final int NUMBER_OF_SPHERES = 4;
+	private static final int NUMBER_OF_LIGHTS = 2;
+	
+	public Example13_2() {
+		super("Example 13.2 - Geom Impostors", 500, 500, true);
+	}
+	
+	@Override
+	public void init() {
+		setFPS(0);
+		
+		glClearColor(0.75f, 0.75f, 1, 1);
+		glClearDepth(1);
+		
+		ViewData viewData = new ViewData(new Vector3(0, 30, 25), new Quaternion(0.3826834f, 0, 0, 0.92387953f), 10, 0);
+		ViewScale viewScale = new ViewScale(3, 70, 3.5f, 1.5f, 5, 1, 90 / 250f);
+		
+		viewPole = new ViewPole(viewData, viewScale, MouseButton.LEFT_BUTTON, false);
+		
+		litMeshProgram = loadLitMeshProgram("example13.2.PN.vert", "example13.2.Lighting.frag");
+		litImpProgram = loadLitImposProgram("example13.2.GeomImpostor.vert", "example13.2.GeomImpostor.geom", "example13.2.GeomImpostor.frag");
+		unlit = loadUnlitProgram("example13.2.Unlit.vert", "example13.2.Unlit.frag");
+		
+		try {
+			planeMesh = new Mesh(getClass().getResource("example13.2.LargePlane.xml"));
+			sphereMesh = new Mesh(getClass().getResource("example13.2.UnitSphere.xml"));
+			cubeMesh = new Mesh(getClass().getResource("example13.2.UnitCube.xml"));
+		} catch(Exception exc) {
+			exc.printStackTrace();
+			destroy();
+		}
+		
+		glEnable(GL_CULL_FACE);
+		glCullFace(GL_BACK);
+		glFrontFace(GL_CW);
+		
+		glEnable(GL_DEPTH_TEST);
+		glDepthMask(true);
+		glDepthFunc(GL_LEQUAL);
+		glDepthRange(0, 1);
+		glEnable(GL_DEPTH_CLAMP);
+		
+		lightUniformBuffer = glGenBuffers();
+		glBindBuffer(GL_UNIFORM_BUFFER, lightUniformBuffer);
+		glBufferData(GL_UNIFORM_BUFFER, LightBlock.SIZE, GL_DYNAMIC_DRAW);
+		
+		projectionUniformBuffer = glGenBuffers();
+		glBindBuffer(GL_UNIFORM_BUFFER, projectionUniformBuffer);
+		glBufferData(GL_UNIFORM_BUFFER, 16 * 4, GL_DYNAMIC_DRAW);
+		
+		glBindBufferRange(GL_UNIFORM_BUFFER, lightBlockIndex, lightUniformBuffer, 0, LightBlock.SIZE);
+		glBindBufferRange(GL_UNIFORM_BUFFER, projectionBlockIndex, projectionUniformBuffer, 0, 16 * 4);
+		
+		glBindBuffer(GL_UNIFORM_BUFFER, 0);
+		
+		impostorVBO = glGenBuffers();
+		glBindBuffer(GL_ARRAY_BUFFER, impostorVBO);
+		glBufferData(GL_ARRAY_BUFFER, NUMBER_OF_SPHERES * 4 * 4, GL_STREAM_DRAW);
+		
+		impostorVAO = glGenVertexArrays();
+		glBindVertexArray(impostorVAO);
+		glEnableVertexAttribArray(0);
+		glVertexAttribPointer(0, 3, GL_FLOAT, false, 16, 0);
+		glEnableVertexAttribArray(1);
+		glVertexAttribPointer(1, 1, GL_FLOAT, false, 16, 12);
+		glBindVertexArray(0);
+		
+		glBindBuffer(GL_ARRAY_BUFFER, 0);
+		
+		glEnable(GL_PROGRAM_POINT_SIZE);
+		
+		createMaterials();
+	}
+	
+	private ProgramMeshData loadLitMeshProgram(String vertexShader, String fragmentShader) {
+		ProgramMeshData data = new ProgramMeshData(new ShaderProgram(readFromFile(vertexShader), readFromFile(fragmentShader)));
+		data.modelToCameraMatrix = glGetUniformLocation(data.program.getProgram(), "modelToCameraMatrix");
+		data.normalModelToCameraMatrix = glGetUniformLocation(data.program.getProgram(), "normalModelToCameraMatrix");
+		
+		int materialBlock = glGetUniformBlockIndex(data.program.getProgram(), "Material");
+		int lightBlock = glGetUniformBlockIndex(data.program.getProgram(), "Light");
+		int projectionBlock = glGetUniformBlockIndex(data.program.getProgram(), "Projection");
+		
+		glUniformBlockBinding(data.program.getProgram(), materialBlock, materialBlockIndex);
+		glUniformBlockBinding(data.program.getProgram(), lightBlock, lightBlockIndex);
+		glUniformBlockBinding(data.program.getProgram(), projectionBlock, projectionBlockIndex);
+		
+		return data;
+	}
+	
+	private ProgramImposData loadLitImposProgram(String vertexShader, String geometryShader, String fragmentShader) {
+		ProgramImposData data = new ProgramImposData(new ShaderProgram(readFromFile(vertexShader), readFromFile(geometryShader), readFromFile(fragmentShader)));
+		
+		int materialBlock = glGetUniformBlockIndex(data.program.getProgram(), "Material");
+		int lightBlock = glGetUniformBlockIndex(data.program.getProgram(), "Light");
+		int projectionBlock = glGetUniformBlockIndex(data.program.getProgram(), "Projection");
+		
+		glUniformBlockBinding(data.program.getProgram(), materialBlock, materialBlockIndex);
+		glUniformBlockBinding(data.program.getProgram(), lightBlock, lightBlockIndex);
+		glUniformBlockBinding(data.program.getProgram(), projectionBlock, projectionBlockIndex);
+		
+		return data;
+	}
+	
+	private UnlitProgramData loadUnlitProgram(String vertexShader, String fragmentShader) {
+		UnlitProgramData data = new UnlitProgramData(new ShaderProgram(readFromFile(vertexShader), readFromFile(fragmentShader)));
+		data.modelToCameraMatrixUniform = glGetUniformLocation(data.program.getProgram(), "modelToCameraMatrix");
+		data.objectColorUniform = glGetUniformLocation(data.program.getProgram(), "objectColor");
+		
+		int projectionBlock = glGetUniformBlockIndex(data.program.getProgram(), "Projection");
+		glUniformBlockBinding(data.program.getProgram(), projectionBlock, projectionBlockIndex);
+		
+		return data;
+	}
+	
+	private void createMaterials() {
+		ArrayList<MaterialEntry> materials = new ArrayList<>();
+		materials.add(new MaterialEntry(new Vector4(0.1f, 0.1f, 0.8f, 1), new Vector4(0.8f, 0.8f, 0.8f, 1), 0.1f));
+		materials.add(new MaterialEntry(new Vector4(0.4f, 0.4f, 0.4f, 1), new Vector4(0.1f, 0.1f, 0.1f, 1), 0.8f));
+		materials.add(new MaterialEntry(new Vector4(0.05f, 0.05f, 0.05f, 1), new Vector4(0.95f, 0.95f, 0.95f, 1), 0.3f));
+		materials.add(new MaterialEntry(new Vector4(0.803f, 0.709f, 0.15f, 1), new Vector4(0.803f, 0.709f, 0.15f, 1).mult(0.75f), 0.18f));
+		
+		materialArrayUniformBuffer = glGenBuffers();
+		materialTerrainUniformBuffer = glGenBuffers();
+		
+		FloatBuffer buffer = BufferUtils.createFloatBuffer(materials.size() * MaterialEntry.SIZE / 4);
+		for(MaterialEntry me : materials)
+			buffer.put(me.toBuffer());
+		buffer.flip();
+		
+		glBindBuffer(GL_UNIFORM_BUFFER, materialArrayUniformBuffer);
+		glBufferData(GL_UNIFORM_BUFFER, buffer, GL_STATIC_DRAW);
+		
+		MaterialEntry material = new MaterialEntry(new Vector4(0.5f, 0.5f, 0.5f, 1), new Vector4(0.5f, 0.5f, 0.5f, 1), 0.6f);
+		glBindBuffer(GL_UNIFORM_BUFFER, materialTerrainUniformBuffer);
+		glBufferData(GL_UNIFORM_BUFFER, material.toBuffer(), GL_STATIC_DRAW);
+		glBindBuffer(GL_UNIFORM_BUFFER, 0);
+	}
+	
+	@Override
+	public void resized() {
+		super.resized();
+		
+		glBindBuffer(GL_UNIFORM_BUFFER, projectionUniformBuffer);
+		glBufferSubData(GL_UNIFORM_BUFFER, 0, new Matrix4().clearToPerspectiveDeg(45, getWidth(), getHeight(), 1, 1000).toBuffer());
+		glBindBuffer(GL_UNIFORM_BUFFER, 0);
+	}
+	
+	@Override
+	public void update(long deltaTime) {
+		sphereTimer.update(deltaTime);
+		
+		Utils.updateMousePoles(viewPole, null);
+		
+		viewPole.charPress(deltaTime);
+	}
+	
+	@Override
+	public void keyPressed(int key, char c) {
+		switch(key) {
+			case Keyboard.KEY_P:
+				sphereTimer.togglePause();
+				break;
+			case Keyboard.KEY_MINUS:
+				sphereTimer.rewind(0.5f);
+				break;
+			case Keyboard.KEY_EQUALS:
+				sphereTimer.fastForward(0.5f);
+				break;
+			case Keyboard.KEY_T:
+				drawCameraPos = !drawCameraPos;
+				break;
+			case Keyboard.KEY_G:
+				drawLights = !drawLights;
+				break;
+		}
+	}
+	
+	private Vector3 getSphereOrbitPosition(MatrixStack modelMatrix, Vector3 orbitCenter, Vector3 orbitAxis, float orbitRadius, float orbitAlpha) {
+		modelMatrix.pushMatrix();
+		
+		try {
+			modelMatrix.getTop().translate(orbitCenter);
+			modelMatrix.getTop().rotateDeg(360 * orbitAlpha, orbitAxis);
+			
+			Vector3 offsetDir = orbitAxis.copy().cross(new Vector3(0, 1, 0));
+			if(offsetDir.length() < 0.001f)
+				offsetDir = orbitAxis.copy().cross(new Vector3(1, 0, 0));
+			
+			offsetDir.normalize();
+			
+			modelMatrix.getTop().translate(offsetDir.mult(orbitRadius));
+			
+			return new Vector3(modelMatrix.getTop().mult(new Vector4(0, 0, 0, 1)));
+		} finally {
+			modelMatrix.popMatrix();
+		}
+	}
+	
+	private Vector4 calcLightPosition() {
+		float currTime = sphereTimer.getAlpha();
+		
+		Vector4 ret = new Vector4(0, 20, 0, 1);
+		ret.x((float)Math.cos(currTime * 2 * Math.PI) * 20);
+		ret.z((float)Math.sin(currTime * 2 * Math.PI) * 20);
+		
+		return ret;
+	}
+	
+	@Override
+	public void render() {
+		glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
+		
+		MatrixStack modelMatrix = new MatrixStack();
+		modelMatrix.setTop(viewPole.calcMatrix());
+		
+		Matrix4 worldToCamMatrix = modelMatrix.getTop();
+		
+		LightBlock lightData = new LightBlock(new Vector4(0.2f, 0.2f, 0.2f, 1), lightAttenuation);
+		lightData.lights[0] = new PerLight(worldToCamMatrix.mult(new Vector4(0.707f, 0.707f, 0, 0)), new Vector4(0.6f, 0.6f, 0.6f, 1));
+		lightData.lights[1] = new PerLight(worldToCamMatrix.mult(calcLightPosition()), new Vector4(0.4f, 0.4f, 0.4f, 1));
+		
+		glBindBuffer(GL_UNIFORM_BUFFER, lightUniformBuffer);
+		glBufferSubData(GL_UNIFORM_BUFFER, 0, lightData.toBuffer());
+		glBindBuffer(GL_UNIFORM_BUFFER, 0);
+		
+		{
+			glBindBufferRange(GL_UNIFORM_BUFFER, materialBlockIndex, materialTerrainUniformBuffer, 0, MaterialEntry.SIZE);
+			
+			litMeshProgram.program.begin();
+			glUniformMatrix4(litMeshProgram.modelToCameraMatrix, false, modelMatrix.getTop().toBuffer());
+			glUniformMatrix3(litMeshProgram.normalModelToCameraMatrix, false, new Matrix3(modelMatrix.getTop()).inverse().transpose().toBuffer());
+			planeMesh.render();
+			litMeshProgram.program.end();
+			
+			glBindBufferBase(GL_UNIFORM_BUFFER, materialBlockIndex, 0);
+		}
+		
+		{
+			VertexData[] posSize = new VertexData[NUMBER_OF_SPHERES];
+			posSize[0] = new VertexData(new Vector3(worldToCamMatrix.mult(new Vector4(0, 10, 0, 1))), 4);
+			posSize[1] = new VertexData(getSphereOrbitPosition(modelMatrix, new Vector3(0, 10, 0), new Vector3(0.6f, 0.8f, 0), 20, sphereTimer.getAlpha()), 2);
+			posSize[2] = new VertexData(getSphereOrbitPosition(modelMatrix, new Vector3(-10, 1, 0), new Vector3(0, 1, 0), 10, sphereTimer.getAlpha()), 1);
+			posSize[3] = new VertexData(getSphereOrbitPosition(modelMatrix, new Vector3(10, 1, 0), new Vector3(0, 1, 0), 10, sphereTimer.getAlpha() * 2), 1);
+			
+			FloatBuffer buffer = BufferUtils.createFloatBuffer(posSize.length * VertexData.SIZE / 4);
+			for(VertexData vd : posSize)
+				buffer.put(vd.toBuffer());
+			buffer.flip();
+			
+			glBindBuffer(GL_ARRAY_BUFFER, impostorVBO);
+			glBufferSubData(GL_ARRAY_BUFFER, 0, buffer);
+			glBindBuffer(GL_ARRAY_BUFFER, 0);
+			
+			glBindBufferRange(GL_UNIFORM_BUFFER, materialBlockIndex, materialArrayUniformBuffer, 0, NUMBER_OF_SPHERES * MaterialEntry.SIZE);
+			
+			litImpProgram.program.begin();
+			glBindVertexArray(impostorVAO);
+			glDrawArrays(GL_POINTS, 0, NUMBER_OF_SPHERES);
+			glBindVertexArray(0);
+			litImpProgram.program.end();
+			
+			glBindBufferBase(GL_UNIFORM_BUFFER, materialBlockIndex, 0);
+		}
+		
+		if(drawLights) {
+			modelMatrix.pushMatrix();
+			
+			modelMatrix.getTop().translate(new Vector3(calcLightPosition()));
+			modelMatrix.getTop().scale(0.5f);
+			
+			unlit.program.begin();
+			glUniformMatrix4(unlit.modelToCameraMatrixUniform, false, modelMatrix.getTop().toBuffer());
+			glUniform4(unlit.objectColorUniform, new Vector4(1).toBuffer());
+			cubeMesh.render("flat");
+			unlit.program.end();
+			
+			modelMatrix.popMatrix();
+		}
+		
+		if(drawCameraPos) {
+			modelMatrix.pushMatrix();
+			
+			modelMatrix.getTop().clearToIdentity();
+			modelMatrix.getTop().translate(0, 0, -viewPole.getView().radius);
+			
+			unlit.program.begin();
+			
+			glDisable(GL_DEPTH_TEST);
+			glDepthMask(false);
+			glUniformMatrix4(unlit.modelToCameraMatrixUniform, false, modelMatrix.getTop().toBuffer());
+			glUniform4f(unlit.objectColorUniform, 0.25f, 0.25f, 0.25f, 1);
+			cubeMesh.render("flat");
+			
+			glDepthMask(true);
+			glEnable(GL_DEPTH_TEST);
+			glUniform4f(unlit.objectColorUniform, 1, 1, 1, 1);
+			cubeMesh.render("flat");
+			
+			unlit.program.end();
+		}
+	}
+	
+	private static class ProgramMeshData {
+		private ShaderProgram program;
+		
+		private int modelToCameraMatrix;
+		private int normalModelToCameraMatrix;
+		
+		public ProgramMeshData(ShaderProgram program) {
+			this.program = program;
+		}
+	}
+	
+	private static class ProgramImposData {
+		private ShaderProgram program;
+		
+		public ProgramImposData(ShaderProgram program) {
+			this.program = program;
+		}
+	}
+	
+	private static class UnlitProgramData {
+		private ShaderProgram program;
+		
+		private int objectColorUniform;
+		private int modelToCameraMatrixUniform;
+		
+		public UnlitProgramData(ShaderProgram program) {
+			this.program = program;
+		}
+	}
+	
+	private static class PerLight {
+		private Vector4 cameraSpaceLightPos;
+		private Vector4 lightIntensity;
+		
+		public static final int SIZE = 2 * 4 * 4;
+		
+		public PerLight(Vector4 cameraSpaceLightPos, Vector4 lightIntensity) {
+			this.cameraSpaceLightPos = cameraSpaceLightPos;
+			this.lightIntensity = lightIntensity;
+		}
+		
+		private static final FloatBuffer buffer = BufferUtils.createFloatBuffer(SIZE / 4);
+		
+		public FloatBuffer toBuffer() {
+			buffer.clear();
+			buffer.put(cameraSpaceLightPos.toBuffer());
+			buffer.put(lightIntensity.toBuffer());
+			buffer.flip();
+			return buffer;
+		}
+	}
+	
+	private static class LightBlock {
+		private Vector4 ambientIntensity;
+		private float lightAttenuation;
+		private PerLight[] lights = new PerLight[NUMBER_OF_LIGHTS];
+		
+		public static final int SIZE = 2 * 4 * 4 + NUMBER_OF_LIGHTS * PerLight.SIZE;
+		
+		public LightBlock(Vector4 ambientIntensity, float lightAttenuation) {
+			this.ambientIntensity = ambientIntensity;
+			this.lightAttenuation = lightAttenuation;
+		}
+		
+		private static final FloatBuffer buffer = BufferUtils.createFloatBuffer(SIZE / 4);
+		
+		public FloatBuffer toBuffer() {
+			buffer.clear();
+			buffer.put(ambientIntensity.toBuffer());
+			buffer.put(lightAttenuation);
+			buffer.put(new float[3]);
+			
+			for(PerLight light : lights)
+				buffer.put(light.toBuffer());
+			
+			buffer.flip();
+			return buffer;
+		}
+	}
+	
+	private static class MaterialEntry implements UniformBlockObject {
+		private Vector4 diffuseColor;
+		private Vector4 specularColor;
+		private float specularShininess;
+		
+		public static final int SIZE = 3 * 4 * 4;
+		
+		public MaterialEntry(Vector4 diffuseColor, Vector4 specularColor, float specularShininess) {
+			this.diffuseColor = diffuseColor;
+			this.specularColor = specularColor;
+			this.specularShininess = specularShininess;
+		}
+		
+		private static final FloatBuffer buffer = BufferUtils.createFloatBuffer(SIZE / 4);
+		
+		public FloatBuffer toBuffer() {
+			buffer.clear();
+			buffer.put(diffuseColor.toBuffer());
+			buffer.put(specularColor.toBuffer());
+			buffer.put(specularShininess);
+			buffer.put(new float[3]);
+			buffer.flip();
+			return buffer;
+		}
+	}
+	
+	private static class VertexData {
+		private Vector3 cameraPosition;
+		private float sphereRadius;
+		
+		public static final int SIZE = 4 * 4;
+		
+		public VertexData(Vector3 cameraPosition, float sphereRadius) {
+			this.cameraPosition = cameraPosition;
+			this.sphereRadius = sphereRadius;
+		}
+		
+		private static final FloatBuffer buffer = BufferUtils.createFloatBuffer(4);
+		
+		public FloatBuffer toBuffer() {
+			buffer.clear();
+			buffer.put(cameraPosition.toBuffer());
+			buffer.put(sphereRadius);
+			buffer.flip();
+			return buffer;
+		}
+	}
+}

src/com/ra4king/opengl/arcsynthesis/gl33/chapter13/example2/example13.2.GeomImpostor.frag

+#version 330
+
+in FragData
+{
+	flat vec3 cameraSpherePos;
+	flat float sphereRadius;
+	smooth vec2 mapping;
+};
+
+out vec4 outputColor;
+
+layout(std140) uniform;
+
+struct MaterialEntry
+{
+	vec4 diffuseColor;
+	vec4 specularColor;
+	vec4 specularShininess;		//ATI Array Bug fix. Not really a vec4.
+};
+
+const int NUMBER_OF_SPHERES = 4;
+
+uniform Material
+{
+	MaterialEntry material[NUMBER_OF_SPHERES];
+} Mtl;
+
+struct PerLight
+{
+	vec4 cameraSpaceLightPos;
+	vec4 lightIntensity;
+};
+
+const int numberOfLights = 2;
+
+uniform Light
+{
+	vec4 ambientIntensity;
+	float lightAttenuation;
+	PerLight lights[numberOfLights];
+} Lgt;
+
+uniform Projection
+{
+	mat4 cameraToClipMatrix;
+};
+
+float calcAttenuation(in vec3 cameraSpacePosition, in vec3 cameraSpaceLightPos, out vec3 lightDirection)
+{
+	vec3 lightDifference =  cameraSpaceLightPos - cameraSpacePosition;
+	float lightDistanceSqr = dot(lightDifference, lightDifference);
+	lightDirection = lightDifference * inversesqrt(lightDistanceSqr);
+	
+	return 1.0 / (1.0 + Lgt.lightAttenuation * lightDistanceSqr);
+}
+
+vec4 computeLighting(in PerLight lightData, in vec3 cameraSpacePosition, in vec3 cameraSpaceNormal, in MaterialEntry material)
+{
+	vec3 lightDir;
+	vec4 lightIntensity;
+	if(lightData.cameraSpaceLightPos.w == 0.0)
+	{
+		lightDir = vec3(lightData.cameraSpaceLightPos);
+		lightIntensity = lightData.lightIntensity;
+	}
+	else
+	{
+		float atten = calcAttenuation(cameraSpacePosition, lightData.cameraSpaceLightPos.xyz, lightDir);
+		lightIntensity = atten * lightData.lightIntensity;
+	}
+	
+	vec3 surfaceNormal = normalize(cameraSpaceNormal);
+	float cosAngIncidence = dot(surfaceNormal, lightDir);
+	cosAngIncidence = cosAngIncidence < 0.0001 ? 0.0 : cosAngIncidence;
+	
+	vec3 viewDirection = normalize(-cameraSpacePosition);
+	
+	vec3 halfAngle = normalize(lightDir + viewDirection);
+	float angleNormalHalf = acos(dot(halfAngle, surfaceNormal));
+	float exponent = angleNormalHalf / material.specularShininess.x;
+	exponent = -(exponent * exponent);
+	float gaussianTerm = exp(exponent);
+
+	gaussianTerm = cosAngIncidence != 0.0 ? gaussianTerm : 0.0;
+	
+	vec4 lighting = material.diffuseColor * lightIntensity * cosAngIncidence;
+	lighting += material.specularColor * lightIntensity * gaussianTerm;
+	
+	return lighting;
+}
+
+void impostor(out vec3 cameraPos, out vec3 cameraNormal)
+{
+	vec3 cameraPlanePos = vec3(mapping * sphereRadius, 0.0) + cameraSpherePos;
+	vec3 rayDirection = normalize(cameraPlanePos);
+	
+	float B = 2.0 * dot(rayDirection, -cameraSpherePos);
+	float C = dot(cameraSpherePos, cameraSpherePos) - (sphereRadius * sphereRadius);
+	
+	float det = (B * B) - (4 * C);
+	if(det < 0.0)
+		discard;
+	
+	float sqrtDet = sqrt(det);
+	float posT = (-B + sqrtDet)/2;
+	float negT = (-B - sqrtDet)/2;
+	
+	float intersectT = min(posT, negT);
+	cameraPos = rayDirection * intersectT;
+	cameraNormal = normalize(cameraPos - cameraSpherePos);
+}
+
+void main()
+{
+	vec3 cameraPos;
+	vec3 cameraNormal;
+	
+	impostor(cameraPos, cameraNormal);
+	
+	vec4 clipPos = cameraToClipMatrix * vec4(cameraPos, 1.0);
+	float ndcDepth = clipPos.z / clipPos.w;
+	gl_FragDepth = ((gl_DepthRange.diff * ndcDepth) + gl_DepthRange.near + gl_DepthRange.far) / 2.0;
+	
+	vec4 accumLighting = Mtl.material[gl_PrimitiveID].diffuseColor * Lgt.ambientIntensity;
+	for(int light = 0; light < numberOfLights; light++)
+	{
+		accumLighting += computeLighting(Lgt.lights[light], cameraPos, cameraNormal, Mtl.material[gl_PrimitiveID]);
+	}
+	
+	outputColor = sqrt(accumLighting);
+}

src/com/ra4king/opengl/arcsynthesis/gl33/chapter13/example2/example13.2.GeomImpostor.geom

+#version 330
+
+layout(std140) uniform;
+layout(points) in;
+layout(triangle_strip, max_vertices=4) out;
+
+uniform Projection
+{
+	mat4 cameraToClipMatrix;
+};
+
+in VertexData
+{
+	vec3 cameraSpherePos;
+	float sphereRadius;
+} vert[];
+
+out FragData
+{
+	flat vec3 cameraSpherePos;
+	flat float sphereRadius;
+	smooth vec2 mapping;
+};
+
+const float g_boxCorrection = 1.5;
+
+void calculatePosition(in vec2 pos, out vec4 position, out int id) {
+	cameraSpherePos = vec3(vert[0].cameraSpherePos);
+	sphereRadius = vert[0].sphereRadius;
+	mapping = pos * g_boxCorrection;
+	
+	vec4 cameraCornerPos = vec4(vert[0].cameraSpherePos, 1.0);
+	cameraCornerPos.xy += vec2(vert[0].sphereRadius, vert[0].sphereRadius) * mapping;
+	position = cameraToClipMatrix * cameraCornerPos;
+	id = gl_PrimitiveIDIn;
+}
+
+void main()
+{
+	calculatePosition(vec2(-1.0, -1.0), gl_Position, gl_PrimitiveID);
+	EmitVertex();
+	
+	calculatePosition(vec2(-1.0, 1.0), gl_Position, gl_PrimitiveID);
+	EmitVertex();
+	
+	calculatePosition(vec2(1.0, -1.0), gl_Position, gl_PrimitiveID);
+	EmitVertex();
+	
+	calculatePosition(vec2(1.0, 1.0), gl_Position, gl_PrimitiveID);
+	EmitVertex();
+}

src/com/ra4king/opengl/arcsynthesis/gl33/chapter13/example2/example13.2.GeomImpostor.vert

+#version 330
+
+layout(location = 0) in vec3 cameraSpherePos;
+layout(location = 1) in float sphereRadius;
+
+out VertexData
+{
+	vec3 cameraSpherePos;
+	float sphereRadius;
+} outData;
+
+void main()
+{
+	outData.cameraSpherePos = cameraSpherePos;
+	outData.sphereRadius = sphereRadius;
+}

src/com/ra4king/opengl/arcsynthesis/gl33/chapter13/example2/example13.2.LargePlane.xml

+<?xml version="1.0" encoding="UTF-8"?>
+<?oxygen RNGSchema="../../Documents/meshFormat.rnc" type="compact"?>
+
+<mesh xmlns="http://www.arcsynthesis.com/gltut/mesh">
+	<attribute index="0" type="float" size="3">
+		30 0 -30
+		30 0 30
+		-30 0 30
+		-30 0 -30
+		30 0 -30
+		30 0 30
+		-30 0 30
+		-30 0 -30
+	</attribute>
+	<attribute index="2" type="float" size="3">
+		0 1 0
+		0 1 0
+		0 1 0
+		0 1 0
+		0 -1 0
+		0 -1 0
+		0 -1 0
+		0 -1 0
+	</attribute>
+	<indices cmd="triangles" type="ushort">
+		0 1 2
+		2 3 0
+		4 6 5
+		6 4 7
+	</indices>
+</mesh>

src/com/ra4king/opengl/arcsynthesis/gl33/chapter13/example2/example13.2.Lighting.frag

+#version 330
+
+in vec3 vertexNormal;
+in vec3 cameraSpacePosition;
+
+out vec4 outputColor;
+
+layout(std140) uniform;
+
+uniform Material
+{
+	vec4 diffuseColor;
+	vec4 specularColor;
+	float specularShininess;
+} Mtl;
+
+struct PerLight
+{
+	vec4 cameraSpaceLightPos;
+	vec4 lightIntensity;
+};
+
+const int numberOfLights = 2;
+
+uniform Light
+{
+	vec4 ambientIntensity;
+	float lightAttenuation;
+	PerLight lights[numberOfLights];
+} Lgt;
+
+float calcAttenuation(in vec3 cameraSpacePosition,
+	in vec3 cameraSpaceLightPos,
+	out vec3 lightDirection)
+{
+	vec3 lightDifference =  cameraSpaceLightPos - cameraSpacePosition;
+	float lightDistanceSqr = dot(lightDifference, lightDifference);
+	lightDirection = lightDifference * inversesqrt(lightDistanceSqr);
+	
+	return 1.0 / (1.0 + Lgt.lightAttenuation * lightDistanceSqr);
+}
+
+vec4 computeLighting(in PerLight lightData, in vec3 cameraSpacePosition, in vec3 cameraSpaceNormal)
+{
+	vec3 lightDir;
+	vec4 lightIntensity;
+	if(lightData.cameraSpaceLightPos.w == 0.0)
+	{
+		lightDir = vec3(lightData.cameraSpaceLightPos);
+		lightIntensity = lightData.lightIntensity;
+	}
+	else
+	{
+		float atten = calcAttenuation(cameraSpacePosition, lightData.cameraSpaceLightPos.xyz, lightDir);
+		lightIntensity = atten * lightData.lightIntensity;
+	}
+	
+	vec3 surfaceNormal = normalize(cameraSpaceNormal);
+	float cosAngIncidence = dot(surfaceNormal, lightDir);
+	cosAngIncidence = cosAngIncidence < 0.0001 ? 0.0 : cosAngIncidence;
+	
+	vec3 viewDirection = normalize(-cameraSpacePosition);
+	
+	vec3 halfAngle = normalize(lightDir + viewDirection);
+	float angleNormalHalf = acos(dot(halfAngle, surfaceNormal));
+	float exponent = angleNormalHalf / Mtl.specularShininess;
+	exponent = -(exponent * exponent);
+	float gaussianTerm = exp(exponent);
+
+	gaussianTerm = cosAngIncidence != 0.0 ? gaussianTerm : 0.0;
+	
+	vec4 lighting = Mtl.diffuseColor * lightIntensity * cosAngIncidence;
+	lighting += Mtl.specularColor * lightIntensity * gaussianTerm;
+	
+	return lighting;
+}
+
+void main()
+{
+	vec4 accumLighting = Mtl.diffuseColor * Lgt.ambientIntensity;
+	for(int light = 0; light < numberOfLights; light++)
+	{
+		accumLighting += computeLighting(Lgt.lights[light], cameraSpacePosition, vertexNormal);
+	}
+	
+	outputColor = sqrt(accumLighting); //2.0 gamma correction
+}

src/com/ra4king/opengl/arcsynthesis/gl33/chapter13/example2/example13.2.PN.vert

+#version 330
+
+layout(std140) uniform;
+
+layout(location = 0) in vec3 position;
+layout(location = 2) in vec3 normal;
+
+out vec3 vertexNormal;
+out vec3 cameraSpacePosition;
+
+uniform Projection
+{
+	mat4 cameraToClipMatrix;
+};
+
+uniform mat4 modelToCameraMatrix;
+uniform mat3 normalModelToCameraMatrix;
+
+void main()
+{
+	vec4 tempCamPosition = modelToCameraMatrix * vec4(position, 1.0);
+    gl_Position = cameraToClipMatrix * tempCamPosition;
+
+    vertexNormal = normalize(normalModelToCameraMatrix * normal);
+    cameraSpacePosition = vec3(tempCamPosition);
+}

src/com/ra4king/opengl/arcsynthesis/gl33/chapter13/example2/example13.2.UnitCube.xml

+<?xml version="1.0" encoding="UTF-8"?>
+<?oxygen RNGSchema="../../Documents/meshFormat.rnc" type="compact"?>
+
+<mesh xmlns="http://www.arcsynthesis.com/gltut/mesh">
+	<attribute index="0" type="float" size="3">
+		0.5 0.5 0.5
+		0.5 -0.5 0.5
+		-0.5 -0.5 0.5
+		-0.5 0.5 0.5
+		0.5 0.5 0.5
+		-0.5 0.5 0.5
+		-0.5 0.5 -0.5
+		0.5 0.5 -0.5
+		0.5 0.5 0.5
+		0.5 0.5 -0.5
+		0.5 -0.5 -0.5
+		0.5 -0.5 0.5
+		0.5 0.5 -0.5
+		-0.5 0.5 -0.5
+		-0.5 -0.5 -0.5
+		0.5 -0.5 -0.5
+		0.5 -0.5 0.5
+		0.5 -0.5 -0.5
+		-0.5 -0.5 -0.5
+		-0.5 -0.5 0.5
+		-0.5 0.5 0.5
+		-0.5 -0.5 0.5
+		-0.5 -0.5 -0.5
+		-0.5 0.5 -0.5
+	</attribute>
+	<attribute index="1" type="float" size="4">
+		0.25 1 0.25 1
+		0.25 1 0.25 1
+		0.25 1 0.25 1
+		0.25 1 0.25 1
+		0.5 0.5 1 1
+		0.5 0.5 1 1
+		0.5 0.5 1 1
+		0.5 0.5 1 1
+		1 0.5 0.5 1
+		1 0.5 0.5 1
+		1 0.5 0.5 1
+		1 0.5 0.5 1
+		1 1 0.5 1
+		1 1 0.5 1
+		1 1 0.5 1
+		1 1 0.5 1
+		0.5 1 1 1
+		0.5 1 1 1
+		0.5 1 1 1
+		0.5 1 1 1
+		1 0.5 1 1
+		1 0.5 1 1
+		1 0.5 1 1
+		1 0.5 1 1
+	</attribute>
+	<attribute index="2" type="float" size="3">
+		0 0 1
+		0 0 1
+		0 0 1
+		0 0 1
+		0 1 0
+		0 1 0
+		0 1 0
+		0 1 0
+		1 0 0
+		1 0 0
+		1 0 0
+		1 0 0
+		0 0 -1
+		0 0 -1
+		0 0 -1
+		0 0 -1
+		0 -1 0
+		0 -1 0
+		0 -1 0
+		0 -1 0
+		-1 0 0
+		-1 0 0
+		-1 0 0
+		-1 0 0
+	</attribute>
+	<vao name="lit">
+		<source attrib="0" />
+		<source attrib="2" />
+	</vao>
+	<vao name="lit-color">
+		<source attrib="0" />
+		<source attrib="1" />
+		<source attrib="2" />
+	</vao>
+	<vao name="color">
+		<source attrib="0" />
+		<source attrib="1" />
+	</vao>
+	<vao name="flat">
+		<source attrib="0" />
+	</vao>
+	<indices cmd="triangles" type="ushort">
+		0 1 2
+		2 3 0
+		4 5 6
+		6 7 4
+		8 9 10
+		10 11 8
+		12 13 14
+		14 15 12
+		16 17 18
+		18 19 16
+		20 21 22
+		22 23 20
+	</indices>
+</mesh>

src/com/ra4king/opengl/arcsynthesis/gl33/chapter13/example2/example13.2.UnitSphere.xml

+<?xml version="1.0" encoding="UTF-8"?>
+<?oxygen RNGSchema="../../Documents/meshFormat.rnc" type="compact"?>
+
+<mesh xmlns="http://www.arcsynthesis.com/gltut/mesh">
+	<attribute index="0" type="float" size="3">
+		0 0.5 0
+		0.17101007166283 0.46984631039295 0
+		0.13835005418451 0.46984631039295 0.10051719811689
+		0.052845018353093 0.46984631039295 0.16264024300704
+		-0.052845018353093 0.46984631039295 0.16264024300704
+		-0.13835005418451 0.46984631039295 0.10051719811689
+		-0.17101007166283 0.46984631039295 2.0942002032593e-017
+		-0.13835005418451 0.46984631039295 -0.10051719811689
+		-0.052845018353093 0.46984631039295 -0.16264024300704
+		0.052845018353093 0.46984631039295 -0.16264024300704
+		0.13835005418451 0.46984631039295 -0.10051719811689
+		0.32139380484327 0.38302222155949 0
+		0.26001305000503 0.38302222155949 0.18891053866504
+		0.099316147583396 0.38302222155949 0.30566367239308
+		-0.099316147583396 0.38302222155949 0.30566367239308
+		-0.26001305000503 0.38302222155949 0.18891053866504
+		-0.32139380484327 0.38302222155949 3.9358089549022e-017
+		-0.26001305000503 0.38302222155949 -0.18891053866504
+		-0.099316147583396 0.38302222155949 -0.30566367239308
+		0.099316147583396 0.38302222155949 -0.30566367239308
+		0.26001305000503 0.38302222155949 -0.18891053866504
+		0.43301270189222 0.25 0
+		0.35031463461102 0.25 0.25451848022756
+		0.13380828366491 0.25 0.41181955177317
+		-0.13380828366491 0.25 0.41181955177317
+		-0.35031463461102 0.25 0.25451848022756
+		-0.43301270189222 0.25 5.3027010602301e-017
+		-0.35031463461102 0.25 -0.25451848022756
+		-0.13380828366491 0.25 -0.41181955177317
+		0.13380828366491 0.25 -0.41181955177317
+		0.35031463461102 0.25 -0.25451848022756
+		0.4924038765061 0.086824088833465 0
+		0.39836310418954 0.086824088833465 0.28942773678193
+		0.15216116593649 0.086824088833465 0.46830391540012
+		-0.15216116593649 0.086824088833465 0.46830391540012
+		-0.39836310418954 0.086824088833465 0.28942773678193
+		-0.4924038765061 0.086824088833465 6.0300091581614e-017
+		-0.39836310418954 0.086824088833465 -0.28942773678193
+		-0.15216116593649 0.086824088833465 -0.46830391540012
+		0.15216116593649 0.086824088833465 -0.46830391540012
+		0.39836310418954 0.086824088833465 -0.28942773678193
+		0.4924038765061 -0.086824088833465 0
+		0.39836310418954 -0.086824088833465 0.28942773678193
+		0.15216116593649 -0.086824088833465 0.46830391540012
+		-0.15216116593649 -0.086824088833465 0.46830391540012
+		-0.39836310418954 -0.086824088833465 0.28942773678193
+		-0.4924038765061 -0.086824088833465 6.0300091581614e-017
+		-0.39836310418954 -0.086824088833465 -0.28942773678193
+		-0.15216116593649 -0.086824088833465 -0.46830391540012
+		0.15216116593649 -0.086824088833465 -0.46830391540012
+		0.39836310418954 -0.086824088833465 -0.28942773678193
+		0.43301270189222 -0.25 0
+		0.35031463461102 -0.25 0.25451848022756
+		0.13380828366491 -0.25 0.41181955177317
+		-0.13380828366491 -0.25 0.41181955177317
+		-0.35031463461102 -0.25 0.25451848022756
+		-0.43301270189222 -0.25 5.3027010602301e-017
+		-0.35031463461102 -0.25 -0.25451848022756
+		-0.13380828366491 -0.25 -0.41181955177317
+		0.13380828366491 -0.25 -0.41181955177317
+		0.35031463461102 -0.25 -0.25451848022756
+		0.32139380484327 -0.38302222155949 0
+		0.26001305000503 -0.38302222155949 0.18891053866504
+		0.099316147583396 -0.38302222155949 0.30566367239308
+		-0.099316147583396 -0.38302222155949 0.30566367239308
+		-0.26001305000503 -0.38302222155949 0.18891053866504
+		-0.32139380484327 -0.38302222155949 3.9358089549022e-017
+		-0.26001305000503 -0.38302222155949 -0.18891053866504
+		-0.099316147583396 -0.38302222155949 -0.30566367239308
+		0.099316147583396 -0.38302222155949 -0.30566367239308
+		0.26001305000503 -0.38302222155949 -0.18891053866504
+		0.17101007166283 -0.46984631039295 0
+		0.13835005418451 -0.46984631039295 0.10051719811689
+		0.052845018353093 -0.46984631039295 0.16264024300704
+		-0.052845018353093 -0.46984631039295 0.16264024300704
+		-0.13835005418451 -0.46984631039295 0.10051719811689
+		-0.17101007166283 -0.46984631039295 2.0942002032593e-017
+		-0.13835005418451 -0.46984631039295 -0.10051719811689
+		-0.052845018353093 -0.46984631039295 -0.16264024300704
+		0.052845018353093 -0.46984631039295 -0.16264024300704
+		0.13835005418451 -0.46984631039295 -0.10051719811689
+		0 -0.5 0
+	</attribute>
+	<attribute index="1" type="float" size="4">
+		1 1 1 1
+		1 1 1 1
+		1 1 1 1
+		1 1 1 1
+		1 1 1 1
+		1 1 1 1
+		1 1 1 1
+		1 1 1 1
+		1 1 1 1
+		1 1 1 1
+		1 1 1 1
+		1 1 1 1
+		1 1 1 1
+		1 1 1 1
+		1 1 1 1
+		1 1 1 1
+		1 1 1 1
+		1 1 1 1
+		1 1 1 1
+		1 1 1 1
+		1 1 1 1
+		1 1 1 1
+		1 1 1 1
+		1 1 1 1
+		1 1 1 1
+		1 1 1 1
+		1 1 1 1
+		1 1 1 1
+		1 1 1 1
+		1 1 1 1
+		1 1 1 1
+		1 1 1 1
+		1 1 1 1
+		1 1 1 1
+		1 1 1 1
+		1 1 1 1
+		1 1 1 1
+		1 1 1 1
+		1 1 1 1
+		1 1 1 1
+		1 1 1 1
+		1 1 1 1
+		1 1 1 1
+		1 1 1 1
+		1 1 1 1
+		1 1 1 1
+		1 1 1 1
+		1 1 1 1
+		1 1 1 1
+		1 1 1 1
+		1 1 1 1
+		1 1 1 1
+		1 1 1 1
+		1 1 1 1
+		1 1 1 1
+		1 1 1 1
+		1 1 1 1
+		1 1 1 1
+		1 1 1 1
+		1 1 1 1
+		1 1 1 1
+		1 1 1 1
+		1 1 1 1
+		1 1 1 1
+		1 1 1 1
+		1 1 1 1
+		1 1 1 1
+		1 1 1 1
+		1 1 1 1
+		1 1 1 1
+		1 1 1 1
+		1 1 1 1
+		1 1 1 1
+		1 1 1 1
+		1 1 1 1
+		1 1 1 1
+		1 1 1 1
+		1 1 1 1
+		1 1 1 1
+		1 1 1 1
+		1 1 1 1
+		1 1 1 1
+	</attribute>
+	<attribute index="2" type="float" size="3">
+		0 1 0
+		0.34202014332567 0.93969262078591 0
+		0.27670010836902 0.93969262078591 0.20103439623379
+		0.10569003670619 0.93969262078591 0.32528048601408
+		-0.10569003670619 0.93969262078591 0.32528048601408
+		-0.27670010836902 0.93969262078591 0.20103439623379
+		-0.34202014332567 0.93969262078591 4.1884004065185e-017
+		-0.27670010836902 0.93969262078591 -0.20103439623379
+		-0.10569003670619 0.93969262078591 -0.32528048601408
+		0.10569003670619 0.93969262078591 -0.32528048601408
+		0.27670010836902 0.93969262078591 -0.20103439623379
+		0.64278760968654 0.76604444311898 0
+		0.52002610001006 0.76604444311898 0.37782107733008
+		0.19863229516679 0.76604444311898 0.61132734478617
+		-0.19863229516679 0.76604444311898 0.61132734478617
+		-0.52002610001006 0.76604444311898 0.37782107733008
+		-0.64278760968654 0.76604444311898 7.8716179098043e-017
+		-0.52002610001006 0.76604444311898 -0.37782107733008
+		-0.19863229516679 0.76604444311898 -0.61132734478617
+		0.19863229516679 0.76604444311898 -0.61132734478617
+		0.52002610001006 0.76604444311898 -0.37782107733008
+		0.86602540378444 0.5 0
+		0.70062926922204 0.5 0.50903696045513
+		0.26761656732982 0.5 0.82363910354633
+		-0.26761656732982 0.5 0.82363910354633
+		-0.70062926922204 0.5 0.50903696045513
+		-0.86602540378444 0.5 1.060540212046e-016
+		-0.70062926922204 0.5 -0.50903696045513
+		-0.26761656732982 0.5 -0.82363910354633
+		0.26761656732982 0.5 -0.82363910354633
+		0.70062926922204 0.5 -0.50903696045513
+		0.98480775301221 0.17364817766693 0
+		0.79672620837908 0.17364817766693 0.57885547356386
+		0.30432233187298 0.17364817766693 0.93660783080025
+		-0.30432233187298 0.17364817766693 0.93660783080025
+		-0.79672620837908 0.17364817766693 0.57885547356386
+		-0.98480775301221 0.17364817766693 1.2060018316323e-016
+		-0.79672620837908 0.17364817766693 -0.57885547356386
+		-0.30432233187298 0.17364817766693 -0.93660783080025
+		0.30432233187298 0.17364817766693 -0.93660783080025
+		0.79672620837908 0.17364817766693 -0.57885547356386
+		0.98480775301221 -0.17364817766693 0
+		0.79672620837908 -0.17364817766693 0.57885547356386
+		0.30432233187298 -0.17364817766693 0.93660783080025
+		-0.30432233187298 -0.17364817766693 0.93660783080025
+		-0.79672620837908 -0.17364817766693 0.57885547356386
+		-0.98480775301221 -0.17364817766693 1.2060018316323e-016
+		-0.79672620837908 -0.17364817766693 -0.57885547356386
+		-0.30432233187298 -0.17364817766693 -0.93660783080025
+		0.30432233187298 -0.17364817766693 -0.93660783080025
+		0.79672620837908 -0.17364817766693 -0.57885547356386
+		0.86602540378444 -0.5 0
+		0.70062926922204 -0.5 0.50903696045513
+		0.26761656732982 -0.5 0.82363910354633
+		-0.26761656732982 -0.5 0.82363910354633
+		-0.70062926922204 -0.5 0.50903696045513
+		-0.86602540378444 -0.5 1.060540212046e-016
+		-0.70062926922204 -0.5 -0.50903696045513
+		-0.26761656732982 -0.5 -0.82363910354633
+		0.26761656732982 -0.5 -0.82363910354633
+		0.70062926922204 -0.5 -0.50903696045513
+		0.64278760968654 -0.76604444311898 0
+		0.52002610001006 -0.76604444311898 0.37782107733008
+		0.19863229516679 -0.76604444311898 0.61132734478617
+		-0.19863229516679 -0.76604444311898 0.61132734478617
+		-0.52002610001006 -0.76604444311898 0.37782107733008
+		-0.64278760968654 -0.76604444311898 7.8716179098043e-017
+		-0.52002610001006 -0.76604444311898 -0.37782107733008
+		-0.19863229516679 -0.76604444311898 -0.61132734478617
+		0.19863229516679 -0.76604444311898 -0.61132734478617
+		0.52002610001006 -0.76604444311898 -0.37782107733008
+		0.34202014332567 -0.93969262078591 0
+		0.27670010836902 -0.93969262078591 0.20103439623379
+		0.10569003670619 -0.93969262078591 0.32528048601408
+		-0.10569003670619 -0.93969262078591 0.32528048601408
+		-0.27670010836902 -0.93969262078591 0.20103439623379
+		-0.34202014332567 -0.93969262078591 4.1884004065185e-017
+		-0.27670010836902 -0.93969262078591 -0.20103439623379
+		-0.10569003670619 -0.93969262078591 -0.32528048601408
+		0.10569003670619 -0.93969262078591 -0.32528048601408
+		0.27670010836902 -0.93969262078591 -0.20103439623379