<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>athile technologies</title>
	<atom:link href="http://athile.net/library/blog/?feed=rss2" rel="self" type="application/rss+xml" />
	<link>http://athile.net/library/blog</link>
	<description>The athile technologies blog</description>
	<lastBuildDate>Mon, 13 Aug 2012 14:27:43 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.2</generator>
		<item>
		<title>August</title>
		<link>http://athile.net/library/blog/?p=1616</link>
		<comments>http://athile.net/library/blog/?p=1616#comments</comments>
		<pubDate>Mon, 13 Aug 2012 14:27:43 +0000</pubDate>
		<dc:creator>arthur</dc:creator>
				<category><![CDATA[company]]></category>

		<guid isPermaLink="false">http://athile.net/library/blog/?p=1616</guid>
		<description><![CDATA[Checking in again! A new job is keeping me too busy to do much with the site. That&#8217;s the bad news.  The good news is the new job has me doing a lot of enjoyable graphics work. I&#8217;m not sure when I&#8217;ll be able to revamp / port / return to the work on athile.net, [...]]]></description>
			<content:encoded><![CDATA[<p>Checking in again!</p>
<p>A new job <em>is </em>keeping me too busy to do much with the site. That&#8217;s the bad news.  The good news is the new job has me doing a lot of enjoyable graphics work.</p>
<p>I&#8217;m not sure when I&#8217;ll be able to revamp / port / return to the work on athile.net, but it is in hibernation not anything worse. I enjoy the graphics work I&#8217;ve done here far too much to consider flat out abandoning it.</p>
]]></content:encoded>
			<wfw:commentRss>http://athile.net/library/blog/?feed=rss2&#038;p=1616</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>What&#8217;s going on?</title>
		<link>http://athile.net/library/blog/?p=1610</link>
		<comments>http://athile.net/library/blog/?p=1610#comments</comments>
		<pubDate>Wed, 27 Jun 2012 19:46:53 +0000</pubDate>
		<dc:creator>arthur</dc:creator>
				<category><![CDATA[company]]></category>

		<guid isPermaLink="false">http://athile.net/library/blog/?p=1610</guid>
		<description><![CDATA[About a month and a half since the last post &#8211; I&#8217;m busy working. However, I&#8217;m exploring the possibility of moving &#8220;Athile Technologies&#8221; from the pseudo-company, hobby project of mine to its own sink-or-swim real business. There are a lot of details to work out. This site may go away or it may stay; the [...]]]></description>
			<content:encoded><![CDATA[<p>About a month and a half since the last post &#8211;</p>
<p>I&#8217;m busy working. However, I&#8217;m exploring the possibility of moving &#8220;Athile Technologies&#8221; from the pseudo-company, hobby project of mine to its own sink-or-swim real business. There are a lot of details to work out. This site may go away or it may stay; the code is going to continue exist and be developed one way or another though!</p>
]]></content:encoded>
			<wfw:commentRss>http://athile.net/library/blog/?feed=rss2&#038;p=1610</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Vacation (from the blog)</title>
		<link>http://athile.net/library/blog/?p=1611</link>
		<comments>http://athile.net/library/blog/?p=1611#comments</comments>
		<pubDate>Sat, 12 May 2012 17:35:55 +0000</pubDate>
		<dc:creator>arthur</dc:creator>
				<category><![CDATA[company]]></category>

		<guid isPermaLink="false">http://athile.net/library/blog/?p=1611</guid>
		<description><![CDATA[I&#8217;m realizing work is keeping me too busy to maintain the habit of posting here with fair frequency.  Work is likely going to be keeping me locked up for at least another month or two.  The blog is not dead! But it might be mid-June before the next post!]]></description>
			<content:encoded><![CDATA[<p>I&#8217;m realizing work is keeping me too busy to maintain the habit of posting here with fair frequency.  Work is likely going to be keeping me locked up for at least another month or two.  The blog is not dead! But it might be mid-June before the next post!</p>
]]></content:encoded>
			<wfw:commentRss>http://athile.net/library/blog/?feed=rss2&#038;p=1611</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Concerning Wheel Reinvention</title>
		<link>http://athile.net/library/blog/?p=1595</link>
		<comments>http://athile.net/library/blog/?p=1595#comments</comments>
		<pubDate>Sun, 06 May 2012 19:15:04 +0000</pubDate>
		<dc:creator>arthur</dc:creator>
				<category><![CDATA[company]]></category>

		<guid isPermaLink="false">http://athile.net/library/blog/?p=1595</guid>
		<description><![CDATA[Here&#8217;s a development pattern I&#8217;ve noticed.  This linear progression certainly doesn&#8217;t apply in all cases &#8211; it branches off in different ways in many cases, but at least sometimes the following pattern seems to occur&#8230; Wheel Reinvention and Understanding Roundness Recognize There&#8217;s Already a Solution Out There Find yourself solving a problem that falls into a [...]]]></description>
			<content:encoded><![CDATA[<p>Here&#8217;s a development pattern I&#8217;ve noticed.  This linear progression certainly doesn&#8217;t apply in all cases &#8211; it branches off in different ways in many cases, but at least <em>sometimes </em>the following pattern seems to occur&#8230;</p>
<h3>Wheel Reinvention and Understanding Roundness</h3>
<ol>
<li><strong>Recognize There&#8217;s </strong><strong>Already a Solution Out There<br />
</strong>Find yourself solving a problem that falls into a general pattern &#8211; the kind of pattern that could be solved with a reusable library or external tool.  You note that to some degree you are most likely reinventing a wheel.  Or perhaps in reading about some other library or tool, you note that you have been trying to invent this yourself.  Either way, someone has already solved this class of problem and you&#8217;re potentially inefficiently redoing that work: should you be?</li>
<li><strong>Research a Complete, Existing Solution<br />
</strong>Read some blog posts, check out some tutorials, skim the API docs, and experiment with an existing library or tool that solves the problem you keep facing.  It&#8217;s a pretty good library.  People are using it.  It looks like it&#8217;s got decent documentation and is actively supported. This looks like a potentially good fit.  Your time is valuable and it sure seems a lot smarter to utilize this rather than reinvent.</li>
<li><strong>Start Using It and Get Frustrated the Solution&#8217;s Complexity<br />
</strong>After spending some time with the existing solution, you grow frustrated that you can&#8217;t quite wrap your head around everything the API /tool is trying to do, that it seems to have too many options, that it tries to solve multiple problems, that it doesn&#8217;t quite <em>fit</em> the problem as you would like, that for one valid or not-so-valid reason <em>it doesn&#8217;t seem to be &#8220;right&#8221; for what you need.</em></li>
<li><strong>Design a Simpler Solution<br />
</strong>Go back to your own code. Use the general concepts from the existing library to write / improve your own solution.  Your own solution is one that you do understand, that is simpler, and more neatly fits the problem as you&#8217;ve conceptualized it.  Yes, you&#8217;ve reinvented the wheel, but actually it&#8217;s likely now a better solution than it was at step 1 (at least in theory, assuming you have the time to complete and test the library) and is tailored nicely to your needs.</li>
<li><strong>The Requirements for Your Solution Grow<br />
</strong>Not too long later, you find your simpler solution growing in requirements and complexity gradually creeping in.  Long story short: the task is no longer a clean re-visioning of that existing solution you read about; it&#8217;s turning into a burdensome, parallel reimplementation.  The price of re-implementation is beginning to outweigh the advantages of that simple solution you had a while ago.</li>
<li><strong>Use the Existing Solution<br />
</strong>Now you get it.  You&#8217;ve spent enough time with the problem class to see why the original authors of that existing library did it the way they did.  Maybe that existing solution still isn&#8217;t perfect in your mind, but at least you see <em>why </em>the features exist.  You know have a fairly strong understanding of <em>the class of problem</em>, even if you don&#8217;t like all the details about this specific existing implementation of a solution.  This key though: you now know enough to understand the general problem space of the existing solution.  You use it instead, get over your frustration with its idiosyncrasies when you think of how much effort reimplementing everything yourself would be, and in general are sufficiently happy with it as a solution.</li>
<li><strong>New Team Members Wonder Why Such a Complex Solution is Being Used<br />
</strong>Now we come full circle. You get why this imperfect, seemingly over-complex tool is being unused; they don&#8217;t.  You&#8217;ve been through Step 1-6; they haven&#8217;t.  They wonder we <em>you </em>would recommend such a needlessly complex tool.  How do you explain what you learned to them in those steps?  If this were easy to answer, couldn&#8217;t that same information have saved you going through those early steps as well and just arrived here where you are immediately?</li>
</ol>
<p>Part of me thinks that the reinvention of the wheel in programming is a inevitable: it&#8217;s part of the learning process.  However, at the same time, there&#8217;s a significant difference between pure reinvention and informed rediscovery (i.e. pulling solutions from thin air is <em>really</em> hard<em>, </em>applying solutions learned elsewhere to your own instance of the problem is <em>much </em>easier).</p>
<p>At the same time, I think there are approaches that acknowledge the need for some degree of reinvention without offering huge jumps in complexity between the new person&#8217;s knowledge base and the full-fledged, robust solution.</p>
<p>I wonder if for many classes of problem if a graduated set of APIs is the solution: i.e. (1) here&#8217;s the basic library that will introduce the concepts and get you started quickly &#8211; but you will hit limitations with any long term use, (2) here&#8217;s the intermediate version of the API that follows the same basic conventions and is a direct super-set when possible, and (3) here&#8217;s the advanced API that does exactly what you need, solves all corner cases, but demands a strong conceptual understanding of the problem class.  A problem with this approach is that the author of a type &#8220;1&#8243; API, in the process of implementing it, builds a knowledge base that makes it easy to implement a type &#8220;2&#8243; API &#8211; so he or she does&#8230;and so on with (2) and (3).  (As an aside, I fear OpenGL has to some degree gone from a &#8220;graduated&#8221; API to an advanced API: this is great for experienced graphics programmers, but a glBegin(GL_QUADS) example sure is an easier starting point for beginners.)</p>
<p>I think it&#8217;s useful to acknowledge that there are different stages of user knowledge when designing an API.  I&#8217;m not sure what the right answer to solving the learning curve versus the power of the solution provided, but it&#8217;s an interesting topic.</p>
]]></content:encoded>
			<wfw:commentRss>http://athile.net/library/blog/?feed=rss2&#038;p=1595</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>What&#8217;s New</title>
		<link>http://athile.net/library/blog/?p=1575</link>
		<comments>http://athile.net/library/blog/?p=1575#comments</comments>
		<pubDate>Fri, 27 Apr 2012 16:48:03 +0000</pubDate>
		<dc:creator>arthur</dc:creator>
				<category><![CDATA[company]]></category>
		<category><![CDATA[status]]></category>

		<guid isPermaLink="false">http://athile.net/library/blog/?p=1575</guid>
		<description><![CDATA[No new work on LxEngine in the last couple weeks, unfortunately. Aggravating not being able to finish off that last chunk of work on normal mapping! I&#8217;ve been busy consulting on a web project. I do have to say that taking up a totally different kind of programming (say, small website programming versus the lower-level [...]]]></description>
			<content:encoded><![CDATA[<p>No new work on LxEngine in the last couple weeks, unfortunately.  Aggravating not being able to finish off that last chunk of work on normal mapping!</p>
<p>I&#8217;ve been busy consulting on a web project. I do have to say that taking up a totally different kind of programming (say, small website programming versus the lower-level desktop graphics) really does work well to break the tendency towards tunnel-vision in solving problems. For example, I still think JQuery is a fantastic example of an API that violates many of the &#8220;rules&#8221; about a good API that I previously held; yet, the API is great in many regards, so that&#8217;s a clear sign that those rules &#8211; like all rules &#8211; have exceptions.  A change in perspective is almost always helpful.</p>
<p>Also, have been reading <a href="https://play.google.com/store/books/details/James_M_Van_Verth_Essential_Mathematics_For_Games_?id=g0-G2Dbk5vEC" target="_blank"><i>Essential Mathematics for Games and Interactive Applications: A Programmer&#8217;s Guide</i></a> at <a href="https://twitter.com/#!/g_truc" target="_blank">Christophe Riccio&#8217;s</a> recommendation.  So far it&#8217;s been an excellent book reminding me of the pure math behind all those math classes I use.  I have to say the Google e-book version could have used a little more editing though&#8230;definitely numerous typographical errors in there that could / should be fixed.</p>
]]></content:encoded>
			<wfw:commentRss>http://athile.net/library/blog/?feed=rss2&#038;p=1575</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Normal Maps: WIP</title>
		<link>http://athile.net/library/blog/?p=1576</link>
		<comments>http://athile.net/library/blog/?p=1576#comments</comments>
		<pubDate>Sat, 14 Apr 2012 03:19:02 +0000</pubDate>
		<dc:creator>arthur</dc:creator>
				<category><![CDATA[lxengine]]></category>
		<category><![CDATA[algorithm]]></category>
		<category><![CDATA[bitangent]]></category>
		<category><![CDATA[derivative]]></category>
		<category><![CDATA[image]]></category>
		<category><![CDATA[math]]></category>
		<category><![CDATA[normal mapping]]></category>
		<category><![CDATA[normal maps]]></category>
		<category><![CDATA[normals]]></category>
		<category><![CDATA[tangent]]></category>

		<guid isPermaLink="false">http://athile.net/library/blog/?p=1576</guid>
		<description><![CDATA[For the record, the below image is not yet correct, but here&#8217;s a first-pass at normal mapping in LxEngine: The tangent vectors are calculated by GLGeom. The algorithm I&#8217;m using is somewhat&#8230;custom. I haven&#8217;t seen an implementation similar to how I&#8217;m attempting it &#8211; and thus suspect that I&#8217;ve missed a key point or two. [...]]]></description>
			<content:encoded><![CDATA[<p>For the record, the below image is not yet correct, but here&#8217;s a first-pass at normal mapping in LxEngine:</p>
<p><a href="http://athile.net/library/blog/wp-content/uploads/2012/04/normalmap.png"><img class="aligncenter size-medium wp-image-1577" title="normalmap" src="http://athile.net/library/blog/wp-content/uploads/2012/04/normalmap-300x210.png" alt="" width="300" height="210" /></a></p>
<p>The tangent vectors are calculated by GLGeom. The algorithm I&#8217;m using is somewhat&#8230;custom. I haven&#8217;t seen an implementation similar to how I&#8217;m attempting it &#8211; and thus suspect that I&#8217;ve missed a key point or two. That&#8217;s okay, however &#8211; this is for fun and to learn something.</p>
<p>The basic approach is to define a function <strong>F(p,v) = dUV</strong>, a function that takes a point on the surface of the mesh and a direction vector and returns the change in UV at that point in that direction. If we constraint this function to only be valid at vertices of the mesh (which is fine, since we&#8217;re only going to use this function at vertex points), then we can define F(p,v) as the weighted average of all the edges adjacent to the vertex at p &#8211; with the weights corresponding to the dot product between v and the direction of that edge.  So if we have F(p,v) defined, that we can find tangent and bitangent by finding directions v where F is at a local maximum. This can be done by simple calculus: where the derivative of a function is 0, it is at a local maximum or minimum. Given that F(p,v) is a fairly simple weighted average, the derivative is not complex and solving for where it is 0 is not complex. Thus we end up with the directions in which U increases most and V increase most&#8230;which, until I locate the flaw in my understanding of the problem, are theoretically the tangent and bitangent directions.</p>
<p>We&#8217;ll see. For now, I have compiling code and a screenshot. That&#8217;s enough for today. Testing and debugging will follow <img src='http://athile.net/library/blog/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
]]></content:encoded>
			<wfw:commentRss>http://athile.net/library/blog/?feed=rss2&#038;p=1576</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>GLGeom v0.0.6 Released!</title>
		<link>http://athile.net/library/blog/?p=1566</link>
		<comments>http://athile.net/library/blog/?p=1566#comments</comments>
		<pubDate>Fri, 13 Apr 2012 00:06:41 +0000</pubDate>
		<dc:creator>arthur</dc:creator>
				<category><![CDATA[glgeom]]></category>
		<category><![CDATA[0.0.6]]></category>
		<category><![CDATA[adjacency]]></category>
		<category><![CDATA[glgeom release]]></category>
		<category><![CDATA[normals]]></category>
		<category><![CDATA[primitive buffer]]></category>
		<category><![CDATA[primitives]]></category>
		<category><![CDATA[primitive_buffer]]></category>
		<category><![CDATA[sphere]]></category>

		<guid isPermaLink="false">http://athile.net/library/blog/?p=1566</guid>
		<description><![CDATA[GLGeom v0.0.6 has been released! GLGeom is the header-only C++ template math library developed in conjunction with LxEngine, modeled after and extending the GLM mathematics library. It provides strongly typed point, vector, and color classes, polygonal mesh and primitives classes (spheres, cylinders, etc.), bounding objects, intersection calculations, and more. Release 0.0.6 contains many improvements and changes. [...]]]></description>
			<content:encoded><![CDATA[<p><strong>GLGeom v0.0.6 has been released!</strong></p>
<p><a href="http://athile.net/library/wiki/index.php?title=Tech/GLGeom">GLGeom </a>is the header-only C++ template math library developed in conjunction with LxEngine, modeled after and extending the <a href="http://glm.g-truc.net/">GLM mathematics library</a>. It provides strongly typed point, vector, and color classes, polygonal mesh and primitives classes (spheres, cylinders, etc.), bounding objects, intersection calculations, and more.</p>
<p>Release 0.0.6 contains <a href="https://github.com/athile/GLGeom/compare/v0.0.5...v0.0.6" target="_blank">many improvements and changes</a>. The most significant changes may be to the <a href="http://www.athile.net/tech/glgeom/v0.0.6/doc/api/html/group__glgeom__extension__primitive__buffer.html" target="_blank">glgeom_extension_primitive_buffer</a> module, a module designed to provide a slightly higher-level, CPU-side take on a vertex array object: it stores a mesh (quads, triangles, lines, points) as well as optional arrays for face properties and vertex properties like normals, colors, and UVs.  It now also includes some basic adjacency information.  All of these properties can be set manually or, when possible, generated automatically.</p>
<p>The full release notes which includes download links, API documentation, and code diffs are located here:</p>
<div style="text-align: center; font-weight: bold;"><a href="http://athile.net/library/wiki/index.php?title=Tech/GLGeom#Version_0.0.6_.282012.04.12.29">GLGeom v0.0.6</a></div>
<p>As it will be for some time, it&#8217;s still a very early release but feedback is greatly appreciated. Leave a comment on the blog!</p>
<h3>Example Code</h3>


<div class="wp-geshi-highlight-wrap5"><div class="wp-geshi-highlight-wrap4"><div class="wp-geshi-highlight-wrap3"><div class="wp-geshi-highlight-wrap2"><div class="wp-geshi-highlight-wrap"><div class="wp-geshi-highlight"><div class="cpp"><pre class="de1"><span class="co1">// Use a utility method to create a basic shape</span>
glgeom<span class="sy4">::</span><span class="me2">primitive_buffer</span> primitive <span class="sy1">=</span> glgeom<span class="sy4">::</span><span class="me2">create_sphere</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy4">;</span>
&nbsp;
<span class="co1">// Automatically compute face normals on the sphere </span>
glgeom<span class="sy4">::</span><span class="me2">compute_face_normals</span><span class="br0">&#40;</span>primitive<span class="br0">&#41;</span><span class="sy4">;</span>
&nbsp;
<span class="co1">//</span>
<span class="co1">// Generate some UV coordinates</span>
<span class="co1">//</span>
<span class="co1">// Use a spherical mapper with a scale transform of 10.</span>
<span class="co1">//</span>
glgeom<span class="sy4">::</span><span class="me2">compute_uv_mapping</span><span class="br0">&#40;</span>
    primitive, <span class="nu0">0</span>,
    <span class="br0">&#91;</span><span class="br0">&#93;</span><span class="br0">&#40;</span><span class="kw4">const</span> glgeom<span class="sy4">::</span><span class="me2">point3f</span><span class="sy3">&amp;</span> position, glgeom<span class="sy4">::</span><span class="me2">vector3f</span><span class="sy3">&amp;</span> normal<span class="br0">&#41;</span> <span class="sy2">-</span><span class="sy1">&gt;</span> glgeom<span class="sy4">::</span><span class="me2">point2f</span> <span class="br0">&#123;</span>
         glgeom<span class="sy4">::</span><span class="me2">point2f</span> baseUV <span class="sy1">=</span> glgeom<span class="sy4">::</span><span class="me2">mapper_spherical</span><span class="br0">&#40;</span>position<span class="br0">&#41;</span><span class="sy4">;</span>
         <span class="kw1">return</span> glgeom<span class="sy4">::</span><span class="me2">scale</span><span class="br0">&#40;</span> baseUV, glgeom<span class="sy4">::</span><span class="me2">vector2f</span><span class="br0">&#40;</span><span class="nu0">10</span>, <span class="nu0">10</span><span class="br0">&#41;</span> <span class="br0">&#41;</span><span class="sy4">;</span>
<span class="br0">&#125;</span><span class="br0">&#41;</span><span class="sy4">;</span></pre></div></div></div></div></div></div></div>


<h3>And a look at the primitive buffer functions&#8230;</h3>
<p>Obviously a little incomplete, but we&#8217;re still at 0.0.6!</p>


<div class="wp-geshi-highlight-wrap5"><div class="wp-geshi-highlight-wrap4"><div class="wp-geshi-highlight-wrap3"><div class="wp-geshi-highlight-wrap2"><div class="wp-geshi-highlight-wrap"><div class="wp-geshi-highlight"><div class="cpp"><pre class="de1"><span class="co1">//===========================================================================//</span>
<span class="co1">// GEOMETRY CREATION</span>
<span class="co1">//===========================================================================//</span>
&nbsp;
<span class="kw2">inline</span> primitive_buffer     create_cube                 <span class="br0">&#40;</span><span class="kw4">void</span><span class="br0">&#41;</span><span class="sy4">;</span>
<span class="kw2">inline</span> primitive_buffer     create_sphere               <span class="br0">&#40;</span><span class="kw4">void</span><span class="br0">&#41;</span><span class="sy4">;</span>
<span class="kw2">inline</span> primitive_buffer     create_cylinder             <span class="br0">&#40;</span><span class="kw4">void</span><span class="br0">&#41;</span><span class="sy4">;</span>
<span class="kw2">inline</span> primitive_buffer     create_cone                 <span class="br0">&#40;</span><span class="kw4">void</span><span class="br0">&#41;</span><span class="sy4">;</span>
<span class="kw2">inline</span> primitive_buffer     create_torus                <span class="br0">&#40;</span><span class="kw4">void</span><span class="br0">&#41;</span><span class="sy4">;</span>
&nbsp;
<span class="kw2">inline</span> primitive_buffer     create_vertex_normals_mesh  <span class="br0">&#40;</span>primitive_buffer<span class="sy3">&amp;</span> mesh<span class="br0">&#41;</span><span class="sy4">;</span>
<span class="kw2">inline</span> primitive_buffer     create_face_normals_mesh    <span class="br0">&#40;</span>primitive_buffer<span class="sy3">&amp;</span> mesh<span class="br0">&#41;</span><span class="sy4">;</span>
&nbsp;
<span class="co1">//===========================================================================//</span>
<span class="co1">// ITERATORS</span>
<span class="co1">//===========================================================================//</span>
&nbsp;
<span class="kw2">inline</span> <span class="kw4">void</span>                 iterate_indices             <span class="br0">&#40;</span>primitive_buffer<span class="sy3">&amp;</span> primitive, 
                                                        std<span class="sy4">::</span><span class="me2">function</span><span class="sy1">&lt;</span><span class="kw4">void</span> <span class="br0">&#40;</span><span class="kw4">size_t</span> faceIndex, glgeom<span class="sy4">::</span><span class="kw4">uint16</span><span class="sy2">*</span> vertexIndices<span class="br0">&#41;</span><span class="sy1">&gt;</span> f<span class="br0">&#41;</span><span class="sy4">;</span>
&nbsp;
<span class="co1">//===========================================================================//</span>
<span class="co1">// BOUNDS</span>
<span class="co1">//===========================================================================//</span>
&nbsp;
<span class="kw2">inline</span> <span class="kw4">void</span>                 compute_bounds              <span class="br0">&#40;</span>primitive_buffer<span class="sy3">&amp;</span> primitive, glgeom<span class="sy4">::</span><span class="me2">abbox3f</span><span class="sy3">&amp;</span> bbox<span class="br0">&#41;</span><span class="sy4">;</span>
<span class="kw2">inline</span> <span class="kw4">void</span>                 compute_bounds              <span class="br0">&#40;</span>primitive_buffer<span class="sy3">&amp;</span> primitive, glgeom<span class="sy4">::</span><span class="me2">bsphere3f</span><span class="sy3">&amp;</span> bsphere<span class="br0">&#41;</span><span class="sy4">;</span>
<span class="kw2">inline</span> <span class="kw4">void</span>                 compute_bounds              <span class="br0">&#40;</span>primitive_buffer<span class="sy3">&amp;</span> primitive, glgeom<span class="sy4">::</span><span class="me2">abbox3f</span><span class="sy3">&amp;</span> bbox, glgeom<span class="sy4">::</span><span class="me2">bsphere3f</span><span class="sy3">&amp;</span> bsphere<span class="br0">&#41;</span><span class="sy4">;</span>
<span class="kw2">inline</span> <span class="kw4">void</span>                 compute_bounding_box        <span class="br0">&#40;</span>primitive_buffer<span class="sy3">&amp;</span> primitive<span class="br0">&#41;</span><span class="sy4">;</span>
<span class="kw2">inline</span> <span class="kw4">void</span>                 compute_bounding_sphere     <span class="br0">&#40;</span>primitive_buffer<span class="sy3">&amp;</span> primitive<span class="br0">&#41;</span><span class="sy4">;</span>
<span class="kw2">inline</span> <span class="kw4">void</span>                 compute_bounds              <span class="br0">&#40;</span>primitive_buffer<span class="sy3">&amp;</span> primitive<span class="br0">&#41;</span><span class="sy4">;</span>
&nbsp;
<span class="co1">//===========================================================================//</span>
<span class="co1">// NORMALS</span>
<span class="co1">//===========================================================================//</span>
&nbsp;
<span class="kw2">inline</span> <span class="kw4">void</span>                 compute_face_normals        <span class="br0">&#40;</span>primitive_buffer<span class="sy3">&amp;</span> primitive<span class="br0">&#41;</span><span class="sy4">;</span>
<span class="kw2">inline</span> <span class="kw4">void</span>                 compute_vertex_normals      <span class="br0">&#40;</span>primitive_buffer<span class="sy3">&amp;</span> primitive<span class="br0">&#41;</span><span class="sy4">;</span>
<span class="kw2">inline</span> <span class="kw4">void</span>                 compute_uv_mapping          <span class="br0">&#40;</span>primitive_buffer<span class="sy3">&amp;</span> primitive, 
                                                        <span class="kw4">size_t</span> channel, 
                                                        std<span class="sy4">::</span><span class="me2">function</span><span class="sy1">&lt;</span>glgeom<span class="sy4">::</span><span class="me2">point2f</span> <span class="br0">&#40;</span><span class="kw4">const</span> glgeom<span class="sy4">::</span><span class="me2">point3f</span><span class="sy3">&amp;</span>, <span class="kw4">const</span> glgeom<span class="sy4">::</span><span class="me2">vector3f</span><span class="sy3">&amp;</span><span class="br0">&#41;</span><span class="sy1">&gt;</span> f<span class="br0">&#41;</span><span class="sy4">;</span>
&nbsp;
<span class="co1">//===========================================================================//</span>
<span class="co1">// ADJACENCY</span>
<span class="co1">//===========================================================================//</span>
&nbsp;
<span class="kw2">inline</span> <span class="kw4">void</span>                 compute_adjacency_vertex_to_faces   <span class="br0">&#40;</span>primitive_buffer<span class="sy3">&amp;</span> primitive<span class="br0">&#41;</span><span class="sy4">;</span>
<span class="kw2">inline</span> <span class="kw4">bool</span>                 verify_adjacency_vertex_to_faces    <span class="br0">&#40;</span>primitive_buffer<span class="sy3">&amp;</span> primitive, 
                                                                <span class="kw4">bool</span> report <span class="sy1">=</span> <span class="kw2">true</span><span class="br0">&#41;</span><span class="sy4">;</span>
&nbsp;
<span class="co1">//===========================================================================//</span>
<span class="co1">// MISC</span>
<span class="co1">//===========================================================================//</span>
&nbsp;
<span class="kw2">inline</span> <span class="kw4">void</span>                 reverse_winding_order       <span class="br0">&#40;</span>primitive_buffer<span class="sy3">&amp;</span> primitive<span class="br0">&#41;</span><span class="sy4">;</span></pre></div></div></div></div></div></div></div>


]]></content:encoded>
			<wfw:commentRss>http://athile.net/library/blog/?feed=rss2&#038;p=1566</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Today&#8217;s Updates</title>
		<link>http://athile.net/library/blog/?p=1564</link>
		<comments>http://athile.net/library/blog/?p=1564#comments</comments>
		<pubDate>Thu, 12 Apr 2012 17:13:27 +0000</pubDate>
		<dc:creator>arthur</dc:creator>
				<category><![CDATA[glgeom]]></category>
		<category><![CDATA[lxengine]]></category>
		<category><![CDATA[adjacency info]]></category>
		<category><![CDATA[error handling]]></category>
		<category><![CDATA[modularity]]></category>
		<category><![CDATA[modules]]></category>
		<category><![CDATA[status]]></category>

		<guid isPermaLink="false">http://athile.net/library/blog/?p=1564</guid>
		<description><![CDATA[What I&#8217;ve been working on today&#8230; Created a stub for lxcore.lib Currently, LxEngine is composed of the following: glgeom (header-only library of math functions) lxengine.lib (where the vast majority of the code is) lxengineapp.exe (a small front-end that drives the code in lxengine.lib) What I&#8217;d like it to be is: glgeom (same as before) lxcore.lib [...]]]></description>
			<content:encoded><![CDATA[<p>What I&#8217;ve been working on today&#8230;</p>
<h3>Created a stub for lxcore.lib</h3>
<p>Currently, LxEngine is composed of the following:</p>
<ul>
<li><strong>glgeom</strong> (header-only library of math functions)</li>
<li><strong>lxengine.lib</strong> (where the vast majority of the code is)</li>
<li><strong>lxengineapp.exe</strong> (a small front-end that drives the code in lxengine.lib)</li>
</ul>
<p>What I&#8217;d like it to be is:</p>
<ul>
<li><strong>glgeom</strong> (same as before)</li>
<li><strong>lxcore.lib</strong> (low-level, standalone functions and data types from lxengine.lib)</li>
<li><strong>lxframework.lib</strong> (the higher-level framework of Engine, Document, View, Element, classes)</li>
<li><strong>lxengine.exe</strong> (slightly larger front-end that drives the framework in a flexible, configurable form)</li>
</ul>
<p>That&#8217;s a bit of an over simplification since there&#8217;s also extension libraries like <strong>lxrasterizer.lib </strong>and plug-ins like <strong>soundAL.dll, </strong>which exist now and will continue to exist.</p>
<p>The general point however is that I want make the framework &#8220;leaner.&#8221;  Right now it has too many specific features (mostly from early development when things weren&#8217;t very modular) and it should really be a rather bare but flexible MVC framework.  Those features belong in plug-ins and extensions. Even the utility stand-alone functions belong elsewhere (lxcore.lib). The end goal is a smaller framework is much better: frameworks are useful &#8211; right up until the point they become bloated and hard to understand (and thus defect prone and with steep learning curves).</p>
<h3>GLGeom Error Handling</h3>
<p>Long story short: all this time, I&#8217;ve been using &#8220;assert(0)&#8221; as an error handling mechanism in GLGeom to keep from tying in any dependencies.  That&#8217;s not a very valid approach&#8230;</p>
<p>So I&#8217;m added a <em>simple</em>, but flexible error handling mechanism instead: <a href="http://athile.net/library/wiki/index.php/Tech/GLGeom/Documentation#Error_Handling">docs here</a>.</p>
<h3>GLGeom Compute Primitive Buffer Adjacency Info</h3>
<p>Still a work-in-progress, I&#8217;m trying to port over some old code that is pretty fast at computing adjacency from a polygon soup.  This is also stressing GLGeom from a new angle, which is helping me fill in the blanks on some of the functionality in this currently-version-0.0.5-library.</p>
<p>Better get back to working on it&#8230;</p>
<p>&nbsp;</p>
]]></content:encoded>
			<wfw:commentRss>http://athile.net/library/blog/?feed=rss2&#038;p=1564</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>GLGeom UV generators</title>
		<link>http://athile.net/library/blog/?p=1534</link>
		<comments>http://athile.net/library/blog/?p=1534#comments</comments>
		<pubDate>Wed, 11 Apr 2012 18:42:45 +0000</pubDate>
		<dc:creator>arthur</dc:creator>
				<category><![CDATA[glgeom]]></category>
		<category><![CDATA[C++11]]></category>
		<category><![CDATA[callbacks]]></category>
		<category><![CDATA[cube mapping]]></category>
		<category><![CDATA[lambdas]]></category>
		<category><![CDATA[mappers]]></category>
		<category><![CDATA[overloads]]></category>
		<category><![CDATA[planar mapping]]></category>
		<category><![CDATA[primitive buffer]]></category>
		<category><![CDATA[spherical]]></category>
		<category><![CDATA[spherical mapping]]></category>
		<category><![CDATA[UV generation]]></category>
		<category><![CDATA[uv mapping]]></category>
		<category><![CDATA[UVs]]></category>

		<guid isPermaLink="false">http://athile.net/library/blog/?p=1534</guid>
		<description><![CDATA[Per Dave&#8217;s request, I&#8217;ve recently added a new function to generate UV coordinates on a glgeom::primitive_buffer. The function name is glgeom::compute_uv_mapping(). The principle is simple: it&#8217;s a callback-based function that iterates over all the vertices and calls the callback to generate a UV coordinate. The existing glgeom_extension_mappers module already provides worker functions to use in [...]]]></description>
			<content:encoded><![CDATA[<p>Per Dave&#8217;s request, I&#8217;ve <a href="https://github.com/athile/GLGeom/commits/master" target="_blank">recently added</a> a new function to generate UV coordinates on a <code>glgeom::primitive_buffer</code>.  The function name is <code>glgeom::compute_uv_mapping()</code>.  </p>
<p>The principle is simple: it&#8217;s a callback-based function that iterates over all the vertices and calls the callback to generate a UV coordinate.  The existing glgeom_extension_mappers module already provides worker functions to use in the callback argument (e.g. <code>mapper_cube</code>, <code>mapper_spherical</code>).</p>
<h3>Images</h3>
<p><a href="http://athile.net/library/blog/wp-content/uploads/2012/04/spherical_mapper.png"><img src="http://athile.net/library/blog/wp-content/uploads/2012/04/spherical_mapper-300x210.png" alt="" title="spherical_mapper" width="300" height="210" class="aligncenter size-medium wp-image-1536" /></a></p>
<p>Above is a spherical mapper with a 10x scale applied to the terrain geometry.</p>
<p><a href="http://athile.net/library/blog/wp-content/uploads/2012/04/cube_mapper.png"><img src="http://athile.net/library/blog/wp-content/uploads/2012/04/cube_mapper-300x210.png" alt="" title="cube_mapper" width="300" height="210" class="aligncenter size-medium wp-image-1537" /></a></p>
<p>Above is a cube mapper with a 10x scale applied to the terrain geometry.</p>
<h3>Code</h3>
<p>The syntax for generating a planar XY mapping is as follows:</p>


<div class="wp-geshi-highlight-wrap5"><div class="wp-geshi-highlight-wrap4"><div class="wp-geshi-highlight-wrap3"><div class="wp-geshi-highlight-wrap2"><div class="wp-geshi-highlight-wrap"><div class="wp-geshi-highlight"><div class="cpp"><pre class="de1">glgeom<span class="sy4">::</span><span class="me2">compute_uv_mapping</span><span class="br0">&#40;</span>primitive, <span class="nu0">0</span>, <span class="br0">&#91;</span><span class="br0">&#93;</span><span class="br0">&#40;</span><span class="kw4">const</span> glgeom<span class="sy4">::</span><span class="me2">point3f</span><span class="sy3">&amp;</span> p, <span class="kw4">const</span> glgeom<span class="sy4">::</span><span class="me2">vector3f</span><span class="sy3">&amp;</span> n<span class="br0">&#41;</span> <span class="sy2">-</span><span class="sy1">&gt;</span> glgeom<span class="sy4">::</span><span class="me2">point2f</span> <span class="br0">&#123;</span>
     <span class="kw1">return</span> glgeom<span class="sy4">::</span><span class="me2">scale</span><span class="br0">&#40;</span> glgeom<span class="sy4">::</span><span class="me2">mapper_planar_xy</span><span class="br0">&#40;</span>p<span class="br0">&#41;</span>, glgeom<span class="sy4">::</span><span class="me2">vector2f</span><span class="br0">&#40;</span><span class="nu0">10</span>, <span class="nu0">10</span><span class="br0">&#41;</span><span class="br0">&#41;</span><span class="sy4">;</span>
<span class="br0">&#125;</span><span class="br0">&#41;</span><span class="sy4">;</span></pre></div></div></div></div></div></div></div>


<p>Using namespace glgeom, it looks like this:</p>


<div class="wp-geshi-highlight-wrap5"><div class="wp-geshi-highlight-wrap4"><div class="wp-geshi-highlight-wrap3"><div class="wp-geshi-highlight-wrap2"><div class="wp-geshi-highlight-wrap"><div class="wp-geshi-highlight"><div class="cpp"><pre class="de1">compute_uv_mapping<span class="br0">&#40;</span>primitive, <span class="nu0">0</span>, <span class="br0">&#91;</span><span class="br0">&#93;</span><span class="br0">&#40;</span><span class="kw4">const</span> point3f<span class="sy3">&amp;</span> p, <span class="kw4">const</span> vector3f<span class="sy3">&amp;</span> n<span class="br0">&#41;</span> <span class="sy2">-</span><span class="sy1">&gt;</span> point2f <span class="br0">&#123;</span>
     <span class="kw1">return</span> scale<span class="br0">&#40;</span> mapper_planar_xy<span class="br0">&#40;</span>p<span class="br0">&#41;</span>, vector2f<span class="br0">&#40;</span><span class="nu0">10</span>, <span class="nu0">10</span><span class="br0">&#41;</span><span class="br0">&#41;</span><span class="sy4">;</span>
<span class="br0">&#125;</span><span class="br0">&#41;</span><span class="sy4">;</span></pre></div></div></div></div></div></div></div>


<p>For anyone living in the dark ages of pre-<a href="http://en.wikipedia.org/wiki/C%2B%2B11" target="_blank">C++11</a>, the above code reads as follows:</p>
<ul>
<li>Compute a UV mapping for &#8220;primitive&#8221;</li>
<li>Store the computed UVs in channel 0</li>
<li>Generate a lambda function as callback&#8230;</li>
<li>&#8230;which takes in a 3d position and a normal and returns a 2d point (i.e. the UV coordinate)</li>
<li>&#8230;which uses the GLGeom built-in &#8220;mapper_planar_xy&#8221; function to generate the UV</li>
<li>&#8230;and lastly applies a scale factor of 10 to both the u and v coordinates</li>
</ul>
<h3>API Design Commentary</h3>
<p>I have to admit, I&#8217;ve not thoroughly satisfied with the resulting code above.  It&#8217;s a bit verbose and has a <em>very high</em> syntactical-boilerplate-to-content ratio.  However, this is the best compromise I&#8217;ve come up with yet.</p>
<h4>What I don&#8217;t like about this design</h4>
<ul>
<li>The lamdba notation is heavy-weight: there&#8217;s almost as much code to define the lambda signature as there is in the lambda body</li>
<li>It&#8217;s possibly too general: in an ideal design, everything should have an immediately obvious place.  Mappers transformations (scaling and rotation) as quite common so I&#8217;d be nice to have a &#8220;built-in&#8221; argument for these rather than relying on the user adding them manually into the lambda (and possibly introducing a typo into the multiplication order)</li>
<li>Is a UV coordinate a &#8220;point&#8221;? In theory yes, in practice UVs are often treated as generic tuples, making the glgeom::point2t type occasionally cumbersome</li>
</ul>
<h4>Why not allow function pointers to be passed in directly?</h4>
<p>I&#8217;d like it better if syntax like this worked:</p>


<div class="wp-geshi-highlight-wrap5"><div class="wp-geshi-highlight-wrap4"><div class="wp-geshi-highlight-wrap3"><div class="wp-geshi-highlight-wrap2"><div class="wp-geshi-highlight-wrap"><div class="wp-geshi-highlight"><div class="cpp"><pre class="de1">  glgeom<span class="sy4">::</span><span class="me2">compute_uv_mapping</span><span class="br0">&#40;</span>primitive, glgeom<span class="sy4">::</span><span class="me2">mapper_cube</span><span class="br0">&#41;</span><span class="sy4">;</span></pre></div></div></div></div></div></div></div>


<p>But this doesn&#8217;t work well.  I want to support mapper functions that require positions and normals (e.g. mapper_cube) as well as those that depend only on position (e.g. mapper_spherical).  I also want to support lambda functions for inlined custom mappers.  Overloading a compute_uv_mapping template method to automatically choose the right variation did not seem to work (VS2010, at least, doesn&#8217;t seem to handle overloading well with lambdas of varying type). The compiler doesn&#8217;t seem to automatically resolve to the right template overload in a way that provides the syntax I&#8217;d like. </p>
<p>With this approach, I ended up with compiler complaints about ambiguous type resolution.</p>
<h4>Why not provide an explicit set of compute_uv_* methods?</h4>
<p>The ugly boilerplate syntax would go away if a series of functions where provided:</p>


<div class="wp-geshi-highlight-wrap5"><div class="wp-geshi-highlight-wrap4"><div class="wp-geshi-highlight-wrap3"><div class="wp-geshi-highlight-wrap2"><div class="wp-geshi-highlight-wrap"><div class="wp-geshi-highlight"><div class="cpp"><pre class="de1">  glgeom<span class="sy4">::</span><span class="me2">compute_uv_cube_mapping</span><span class="br0">&#40;</span>primitive, uv_transform<span class="br0">&#41;</span><span class="sy4">;</span>
  glgeom<span class="sy4">::</span><span class="me2">compute_uv_spherical_mapping</span><span class="br0">&#40;</span>primitive, uv_transform<span class="br0">&#41;</span><span class="sy4">;</span>
  glgeom<span class="sy4">::</span><span class="me2">compute_uv_planar_xy_mapping</span><span class="br0">&#40;</span>primitive, uv_transform<span class="br0">&#41;</span><span class="sy4">;</span>
  ...</pre></div></div></div></div></div></div></div>


<p>I like this approach that (a) syntax doesn&#8217;t get in the way and (b) it leads to about as self-documenting code as is possible.</p>
<p>What I don&#8217;t like is (a) it requires a mirror function for every mapper defined in the <code>glgeom_extension_mappers</code> and (b) creates a dependency between the <code>glgeom_extension_mappers</code> module and the <code>glgeom_extension_primitive_buffer</code> module.</p>
<h4>So&#8230;?</h4>
<p>I much prefer the <em>principle</em> that a generic function to apply an mapper exists <em>alongside and independent of</em> the set of mappers that can be applied (i.e. something a bit more along the lines of <a href="http://en.wikipedia.org/wiki/Functional_programming" target="_blank">functional programming</a>, thank you Javascript and <a href="http://jquery.com/" target="_blank">JQuery</a> for teaching me how nice this approach can be!).  With that principle in mind, I&#8217;ve ended up with the syntactically verbose lambda based approach.</p>
<h3>What&#8217;s Next?</h3>
<p>Hopefully, generating tangents and bi-tangents.  I <a href="http://athile.net/library/blog/?p=985" target="_blank">wrote a bit before</a> about bump mapping and generating those values in the GLSL shader, but it would be nice to compute such data easily on the CPU side as well.</p>
<p>In any case, this will require me to add some functions to compute mesh adjacency information for a primitive buffer &#8211; a feature I&#8217;ve been meaning to add anyway.</p>
]]></content:encoded>
			<wfw:commentRss>http://athile.net/library/blog/?feed=rss2&#038;p=1534</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Wireframe Overlay</title>
		<link>http://athile.net/library/blog/?p=1527</link>
		<comments>http://athile.net/library/blog/?p=1527#comments</comments>
		<pubDate>Wed, 11 Apr 2012 02:06:25 +0000</pubDate>
		<dc:creator>arthur</dc:creator>
				<category><![CDATA[lxengine]]></category>
		<category><![CDATA[cookbook]]></category>
		<category><![CDATA[glsl]]></category>
		<category><![CDATA[nVidia]]></category>
		<category><![CDATA[shaders]]></category>
		<category><![CDATA[surface and wireframe]]></category>
		<category><![CDATA[viewport matrix]]></category>
		<category><![CDATA[viewportMatrix]]></category>
		<category><![CDATA[wireframe]]></category>

		<guid isPermaLink="false">http://athile.net/library/blog/?p=1527</guid>
		<description><![CDATA[Added a new effect to Tutorial 5: a single-pass surface and wireframe rendering effect. Note how the wireframe is anti-aliased, fades into the surface color, and displays without z-fighting. The effect derives directly from the shader in the previously mentioned OpenGL 4.0 Shading Cookbook. The implementation there, according to the author, derives from the one [...]]]></description>
			<content:encoded><![CDATA[<p>Added a new effect to Tutorial 5: a single-pass surface and wireframe rendering effect.  Note how the wireframe is anti-aliased, fades into the surface color, and displays without z-fighting.</p>
<p><a href="http://athile.net/library/blog/wp-content/uploads/2012/04/wireframe_overlay.png"><img src="http://athile.net/library/blog/wp-content/uploads/2012/04/wireframe_overlay-300x210.png" alt="" title="wireframe_overlay" width="300" height="210" class="aligncenter size-medium wp-image-1528" /></a></p>
<p><a href="http://athile.net/library/blog/wp-content/uploads/2012/04/wireframe_overlay1.png"><img src="http://athile.net/library/blog/wp-content/uploads/2012/04/wireframe_overlay1-300x210.png" alt="" title="wireframe_overlay" width="300" height="210" class="aligncenter size-medium wp-image-1530" /></a></p>
<p>The effect derives directly from the shader in the previously mentioned <a href="http://www.packtpub.com/opengl-4-0-shading-language-cookbook/book" target="_blank">OpenGL 4.0 Shading Cookbook</a>.  The implementation there, according to the author, derives from the one presented in this <a href="http://developer.download.nvidia.com/whitepapers/2007/SDK10/SolidWireframe.pdf" target="_blank">nVidia whitepaper</a>.  I won&#8217;t go into detail of the effect (since the explanation is available both in the whitepaper and the book) and will only briefly comment on the implemenation.</p>
<p>In short, it uses a geometry shader to compute the distance of each fragment from each edge of each triangle.  The fragment shader then uses those distances to determine whether to use the surface shading color or the wireframe edge color.  A mix() call is rather than a discrete choice to antialias the edges.  Because it&#8217;s a single pass shader, there&#8217;s no chance of z-fighting.</p>
<h3>Setting the &#8220;ViewportMatrix&#8221;</h3>
<p>A quick note since the OpenGL 4.0 Shading Cookbook does not explain how to set up the &#8220;ViewportMatrix&#8221;.  It&#8217;s pretty simple, but just to clarify, here&#8217;s the code to set up the viewport matrix:</p>


<div class="wp-geshi-highlight-wrap5"><div class="wp-geshi-highlight-wrap4"><div class="wp-geshi-highlight-wrap3"><div class="wp-geshi-highlight-wrap2"><div class="wp-geshi-highlight-wrap"><div class="wp-geshi-highlight"><div class="cpp"><pre class="de1">GLint viewport<span class="br0">&#91;</span><span class="nu0">4</span><span class="br0">&#93;</span><span class="sy4">;</span>
gl<span class="sy2">-</span><span class="sy1">&gt;</span>getIntegerv<span class="br0">&#40;</span>GL_VIEWPORT, viewport<span class="br0">&#41;</span><span class="sy4">;</span>
&nbsp;
<span class="kw4">float</span> halfWidth <span class="sy1">=</span> <span class="kw4">float</span><span class="br0">&#40;</span>viewport<span class="br0">&#91;</span><span class="nu0">2</span><span class="br0">&#93;</span><span class="br0">&#41;</span> <span class="sy2">/</span> <span class="nu17">2.0f</span><span class="sy4">;</span>
<span class="kw4">float</span> halfHeight <span class="sy1">=</span> <span class="kw4">float</span><span class="br0">&#40;</span>viewport<span class="br0">&#91;</span><span class="nu0">3</span><span class="br0">&#93;</span><span class="br0">&#41;</span> <span class="sy2">/</span> <span class="nu17">2.0f</span><span class="sy4">;</span>
&nbsp;
glm<span class="sy4">::</span><span class="me2">mat4</span> m<span class="br0">&#40;</span>
    glm<span class="sy4">::</span><span class="me2">vec4</span><span class="br0">&#40;</span>halfWidth, <span class="nu17">0.0f</span>, <span class="nu17">0.0f</span>, <span class="nu17">0.0f</span><span class="br0">&#41;</span>,
    glm<span class="sy4">::</span><span class="me2">vec4</span><span class="br0">&#40;</span><span class="nu17">0.0f</span>, halfHeight, <span class="nu17">0.0f</span>, <span class="nu17">0.0f</span><span class="br0">&#41;</span>,
    glm<span class="sy4">::</span><span class="me2">vec4</span><span class="br0">&#40;</span><span class="nu17">0.0f</span>, <span class="nu17">0.0f</span>, <span class="nu17">1.0f</span>, <span class="nu17">0.0f</span><span class="br0">&#41;</span>,
    glm<span class="sy4">::</span><span class="me2">vec4</span><span class="br0">&#40;</span>halfWidth, halfHeight, <span class="nu17">0.0f</span>, <span class="nu17">1.0f</span><span class="br0">&#41;</span>
<span class="br0">&#41;</span><span class="sy4">;</span>
&nbsp;
gl<span class="sy2">-</span><span class="sy1">&gt;</span>uniformMatrix4fv<span class="br0">&#40;</span>loc, <span class="nu0">1</span>, GL_FALSE, glm<span class="sy4">::</span><span class="me2">value_ptr</span><span class="br0">&#40;</span>m<span class="br0">&#41;</span><span class="br0">&#41;</span><span class="sy4">;</span></pre></div></div></div></div></div></div></div>


<p>The principle is quite simple. Prior to the viewport matrix transformation, OpenGL coordinates in eye space range from -1 to 1 in x, y, and z.  Therefore, these values get scaled by half the width/height and offset by half the width/height.  This maps -1 to 0 (e.g. -halfWidth + halfWidth = 0) and 1 to the full width (halfWidth + halfWidth = width).  The z values do not get scaled or offset since window coordinate retain the same range as eye coordinates.</p>
<h3>One More Image&#8230;</h3>
<p><a href="http://athile.net/library/blog/wp-content/uploads/2012/04/wireframe_overlay2.png"><img src="http://athile.net/library/blog/wp-content/uploads/2012/04/wireframe_overlay2-300x210.png" alt="" title="wireframe_overlay" width="300" height="210" class="aligncenter size-medium wp-image-1532" /></a></p>
<p>One last image of a slightly tweaked version of the shader that fades the wireframe intensity based on the diffuse intensity.  Also, snow <img src='http://athile.net/library/blog/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
]]></content:encoded>
			<wfw:commentRss>http://athile.net/library/blog/?feed=rss2&#038;p=1527</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
