<?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>Ahruman’s Webthing &#187; Oolite</title>
	<atom:link href="http://jens.ayton.se/blag/tags/oolite/feed/" rel="self" type="application/rss+xml" />
	<link>http://jens.ayton.se/blag</link>
	<description>Cocoa coding stuff, when I can be bothered.</description>
	<lastBuildDate>Thu, 25 Aug 2011 21:56:35 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.1</generator>
		<item>
		<title>Property List Extractors</title>
		<link>http://jens.ayton.se/blag/property-list-extractors/</link>
		<comments>http://jens.ayton.se/blag/property-list-extractors/#comments</comments>
		<pubDate>Tue, 15 Apr 2008 17:42:43 +0000</pubDate>
		<dc:creator>Jens Ayton</dc:creator>
				<category><![CDATA[Cocoa]]></category>
		<category><![CDATA[Code]]></category>
		<category><![CDATA[Oolite]]></category>
		<category><![CDATA[code-reuse]]></category>
		<category><![CDATA[collections]]></category>

		<guid isPermaLink="false">http://jens.ayton.se/blag/property-list-extractors/</guid>
		<description><![CDATA[Continuing a theme of tearing out useful bits of functionality from Oolite, and inspired by recent Twitter exchanges with Craig Hockenberry and Rainer Brockerhoff, here’s some really boring code for you all – gruntwork that you don’t want to repeat, &#8230; <a href="http://jens.ayton.se/blag/property-list-extractors/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>Continuing <a href="/blag/tags/oolite/">a theme</a> of tearing out useful bits of functionality from <a href="http://oolite.org/">Oolite</a>, and inspired by recent Twitter exchanges with <a href="http://twitter.com/ahruman/statuses/786085836">Craig Hockenberry</a> and <a href="http://twitter.com/ahruman/statuses/788799034">Rainer Brockerhoff</a>, here’s some really boring code for you all – gruntwork that you don’t want to repeat, but should probably be using.</p>
<p>Executive summary for people who don’t like rambling anecdotes: property lists and user defaults should always be type-checked, and this makes it easy.</p>
<p>Oolite is highly moddable, with <a href="http://wiki.alioth.net/index.php/OXP">over 150 expansion packs</a>. Most of them are interoperable, and typically many will be in use at once. Essentially all of these contain property lists, generally written by hand by non-programmers, often on systems without plutil or Property List Editor. As such, many contain parse errors or structural problems.</p>
<p>Previous versions of Oolite blithely ignored the imperfections of mere humans. Unparseable property lists were effectively ignored, leading to unexpected behaviour, often quite subtle. Structural errors, however, caused exceptions, most of them seemingly at random.</p>
<p>The current test releases address the syntax issues by dumping the error string from <code class="objc-code">NSPropertyListSerialization</code> and the path to the relevant file to the game’s run log. A certain amount of context-sensitive type checking is done in certain areas, such as scripting (yes, property lists are used for scripting, although that’ll be deprecated in the next stable release).</p>
<p>The most significant fix, however, has been to replace most uses of <code class="objc-code">-objectForKey:</code> and <code class="objc-code">-objectAtIndex:</code> with methods that check types and perform conversions where they make sense. In particular, strings are automatically converted to numbers and booleans where appropriate, which is needed to work with the more pleasant OpenStep plist syntax. When a plist value can’t be converted to the required type, or simply isn’t there, an appropriate default value is used. The game will no longer try to get keyed objects from an array, or find the first character of a dictionary. Instead of code like this:</p>
<pre class="objc-code">// Hope plist has correct structure.
unsigned myMagicNumber = [[[plist objectForKey:@"someArray"] objectAtIndex:3] unsignedIntValue];</pre>
<p>or more fault-tolerant code like this:</p>
<pre class="objc-code">unsigned myMagicNumber = 0;
id array = [plist objectForKey:@"someArray"];
if ([array isKindOfClass:[NSArray class]] &#038;&#038; [array count] > 3)
{
    id number = [array objectAtIndex:3];
    if ([number respondsToSelector:@selector(unsignedIntValue)])
    {
        myMagicNumber = [number unsignedIntValue];
    }
}</pre>
<p>we now have code like this:</p>
<pre class="objc-code">unsigned myMagicNumber = [[plist arrayForKey:@"someArray"] unsignedIntAtIndex:3];</pre>
<p>which will not throw an exception if <code class=objc-code">@"someArray"</code> is not an array or if the array has less than four members, but will instead return 0. It’s also shorter than the broken version. Default values other than 0 can be provided in the form <code class="objc-code">[array integerAtIndex:3 defaultValue:-1]</code> or <code class="objc-code">[dictionary unsignedShortForKey:@"value" defaultValue:14]</code>.</p>
<p>Oolite is obviously an extreme case, but many applications deal with property lists. Even more deal with <code class="objc-code">NSUserDefaults</code>, which of course is a wrapper around property lists. You may think that you know what you’re putting into user defaults and can therefore rely on it to be correctly structured, but if you’re thinking that you’re wrong. First, users <em>will</em> modify your preferences file, break it, and forget they did it. Second, your code is buggy. If you write any sort of collection to your prefs, there’s a chance that you’ll put an object of the wrong class there if the phase of the moon is unusual. If you don’t check it when you read it, this will cause an exception, and you’ll end up guiding a user through digging around in ~/Library to clean up your mess. Better to be fault-tolerant to start with.</p>
<p>So, here it is: <a href="http://code.google.com/p/ahruman/source/browse/#svn/tags/Foundational/JAPropertyListAccessors%3Fstate%3Dclosed">JAPropertyListAccessors 1.0.2</a> (<a href="http://opensource.org/licenses/mit-license.html">MIT/X11 license</a>). It provides:</p>
<ul>
<li>A non-throwing variant of <code class="objc-code">-[NSArray objectAtIndex:]</code>.</li>
<li>Functions to convert objects (NSNumber or NSString) to all standard integer types, as well as float and double, clamping the results rather than overflowing, and returning a user-specified default value if no conversion can be performed.</li>
<li>Convenience methods for accessing integers, floats, strings, arrays, dictionaries, sets, or objects of a specified class from <code class="objc-code">NSArray</code>, <code class="objc-code">NSDictionary</code> or <code class="objc-code">NSUserDefaults</code>. The following transparent conversions are performed when appropriate: <code class="objc-code">NSString</code> to numbers; <code class="objc-code">NSNumber</code> and <code class="objc-code">NSDate</code> to <code class="objc-code">NSString</code>; <code class="objc-code">NSArray</code> to <code class="objc-code">NSSet</code>.
<li>Convenience methods to set integers and floating-point values in <code class="objc-code">NSMutableArray</code>, <code class="objc-code">NSMutableDictionary</code> and <code class="objc-code">NSUserDefaults</code>.</li>
<li> Unit tests for the primitive conversion functions.</li>
<li> Compatible with 32-bit and 64-bit runtimes, and with garbage-collected and non-GC code.</li>
<li> Very little in the way of comments.</li>
<p></u></p>
<p><em>Update (version 1.0.1):</em> Default value (rather than nil) is now returned when conversion to string fails. String conversion now uses <code class="objc-code">-stringValue</code> if available.</p>
]]></content:encoded>
			<wfw:commentRss>http://jens.ayton.se/blag/property-list-extractors/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Priority Queue</title>
		<link>http://jens.ayton.se/blag/priority-queue/</link>
		<comments>http://jens.ayton.se/blag/priority-queue/#comments</comments>
		<pubDate>Fri, 14 Sep 2007 16:01:10 +0000</pubDate>
		<dc:creator>Jens Ayton</dc:creator>
				<category><![CDATA[Cocoa]]></category>
		<category><![CDATA[Code]]></category>
		<category><![CDATA[Oolite]]></category>

		<guid isPermaLink="false">http://jens.ayton.se/blag/priority-queue/</guid>
		<description><![CDATA[The Foundation framework: it has some collections. It doesn’t have others. In particular, it doesn’t have a priority queue, which I need. CoreFoundation does, but this is for Oolite so it needs to work with GNUstep. Yes, I could bring &#8230; <a href="http://jens.ayton.se/blag/priority-queue/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>The Foundation framework: it has some collections. It doesn’t have others.</p>
<p>In particular, it doesn’t have a priority queue, which I need. CoreFoundation <a href="http://developer.apple.com/documentation/CoreFoundation/Reference/CFBinaryHeapRef/Reference/reference.html">does</a>, but this is for Oolite so it needs to work with GNUstep. Yes, I could bring in all of CFLite, but without the toll-free-bridging it’s not particularly attractive.</p>
<p>Mike Ash (who seems to be getting an indecent amount of exposure in this blog, to the extent that it counts as an exposed location) <a href="http://www.mikeash.com/blog/pivot/entry.php?id=20">wrote</a> about the issue last year. His solution was to use the C++ Standard Template Library, but I don’t like that solution much because a) GNUstep doesn’t play nice with Objective-C++ (its headers aren’t C++-clean) and b) it’s C++.</p>
<p>So, as you may have guessed, I’ve gone and written one. <a href="http://jens.ayton.se/code/files/japriorityqueue.zip">Here it is</a>, with the small amount of Oolite dependency ripped out. MIT/X11 license.</p>
<h4>Operations supported:</h4>
<ul>
<li> Add object.</li>
<li> Add all objects in a collection (anything that responds to <code>-objectEnumerator</code> or <code>-nextObject</code>).
<li> Retrieve highest-priority object. Priority is defined by a comparison method specified when creating the priority queue. Priority is defined such that the <code>NSOrderedDescending</code>most object has the highest priority; as such, using <code>caseInsensitiveCompare:</code> as the comparator will cause strings to be retrieved in lexicographic order.
<li> Delete highest-priority object.
<li> Delete specific object.
<li> Delete equal object (i.e., delete one object such that the comparator returns <code>NSOrderedSame</code>).
<li> Retrieve all objects in sorted order, emptying the queue.</li>
<li> Equality testing and (low-quality) hashing.</li>
<li> Copying of the entire queue.</li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://jens.ayton.se/blag/priority-queue/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>GLSL uniform bindings for Cocoa</title>
		<link>http://jens.ayton.se/blag/glsl-uniform-bindings-for-cocoa/</link>
		<comments>http://jens.ayton.se/blag/glsl-uniform-bindings-for-cocoa/#comments</comments>
		<pubDate>Mon, 30 Jul 2007 22:24:01 +0000</pubDate>
		<dc:creator>Jens Ayton</dc:creator>
				<category><![CDATA[Cocoa]]></category>
		<category><![CDATA[Oolite]]></category>
		<category><![CDATA[OpenGL]]></category>

		<guid isPermaLink="false">http://jens.ayton.se/blag/glsl-uniform-bindings-for-cocoa/</guid>
		<description><![CDATA[Executive summary: This article demonstrates the use of Objective-C’s dynamic object model and the Foundation framework to extract attributes from objects using information not available at compile time. This is done on the context of implementing OpenGL Shader Language support &#8230; <a href="http://jens.ayton.se/blag/glsl-uniform-bindings-for-cocoa/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p><strong>Executive summary:</strong> This article demonstrates the use of Objective-C’s dynamic object model and the Foundation framework to extract attributes from objects using information not available at compile time. This is done on the context of implementing <a title="GLSL – Wikipedia" href="http://en.wikipedia.org/wiki/GLSL">OpenGL Shader Language</a> support in a cross-platform game.</p>
<h3>Introduction</h3>
<p>A major feature of the current development line of <a href="http://oolite.aegidian.org/">Oolite</a> is support for <a title="GLSL – Wikipedia" href="http://en.wikipedia.org/wiki/GLSL">GLSL</a> shaders. Shaders need to be able to reflect the state of the object they’re attached to – for instance, by having spaceship engines glow in proportion to engine power. The mechanism GLSL provides for this is uniform variables, attributes set by the host application and read by the shader.</p>
<p class="imgcaption"><img src="http://jens.ayton.se/blag/wp-content/uploads/2007/07/uniform-bindings-3.png" height="382" width="382" alt="A screen shot of Oolite." /><br clear="all" /><br />
Debris model with per-pixel lighting and heat glow which fades over time from <a href="http://www.aegidian.org/bb/viewtopic.php?p=38444#38444" title="Shader’s Outpost – Oolite Bulletins">glow_alloy.oxp</a>. Model by Arexack_Heretic, textures by Griff, shaders by Ahruman.</p>
<p><span id="more-14"></span></p>
<p>The initial implementation of shader support was quite simplistic:</p>
<pre class="objc-code">for (<em>each material in model</em>)
{
    if (<em>material is shader-based</em>)
    {
        glUseProgramObjectARB(shader);
        if (<em>shader uses uniform:"time"</em>)
        {
            glUniform1fARB(<em>location for "time"</em>, <em>current game time</em>);
        }
        if (<em>shader uses uniform:"engine_level"</em>)
        {
            glUniform1fARB(<em>location for "engine_level"</em>, <em>ship’s engine power level</em>);
        }
        …
    }
    else
    {
        glUseProgramObjectARB(NULL);
        <em>set up texture</em>;
    }
    <em>render geometry for this material</em>;
}</pre>
<h3>The problem</h3>
<p>This gets the job done, but it isn’t exactly a paragon of object-oriented design. There’s no encapsulation and no reuse. It’s definitely not very Cocoa-ey. The first step was obviously to make materials into a class hierarchy, with simple texture-based materials being one class, shader materials being another and the rendering code not really caring which was being used. However, if the shader material class set uniforms in the way outlined above, it would require the shader material class to know about the details of the various types of entity in the game, and special-case each one. Conversely, if the responsibility for setting up uniforms remained in the entity classes, they would need to know about the details of shaders.</p>
<p>So how does Cocoa handle comparable situations? Key-value coding. Key-value observation. Bindings.</p>
<p>As it stands, KVC doesn’t really suit our needs. Accessors for relevant properties tend not to return objects. Properties of potential interest to shaders tend to be numbers, vectors, matrices, quaternions (Oolite will convert quaternions to either vectors or rotation matrices for shader bindings) and colours. Colours are represented by objects, but the others are generally not. So I decided to roll my own.</p>
<h3>Getting the goods</h3>
<p>This turned out to be almost disappointingly simple, although there was a complication arising from the need to support <a title="GNUstep.org" href="http://gnustep.org/">GNUstep</a> as well as <a title="Cocoa – Apple Developer Connection" href="http://developer.apple.com/cocoa/">Cocoa</a>. First, in order to support multiple types, we need to use <code>-[NSObject <a title="NSObject Class Reference – Apple Developer Connection" href="http://developer.apple.com/documentation/Cocoa/Reference/Foundation/Classes/NSObject_Class/Reference/Reference.html#//apple_ref/occ/instm/NSObject/methodSignatureForSelector:">methodSignatureForSelector:</a>]</code> to check the return type of the requested method. Then (assuming the type is supported, and other sanity checks), <code>-[NSObject <a title="NSObject Class Reference – Apple Developer Connection" href="http://developer.apple.com/documentation/Cocoa/Reference/Foundation/Classes/NSObject_Class/Reference/Reference.html#//apple_ref/occ/instm/NSObject/methodForSelector:">methodForSelector:</a>]</code>, which returns an <code><a title="NSObject Class Reference – Apple Developer Connection" href="http://developer.apple.com/documentation/Cocoa/Reference/Foundation/Classes/NSObject_Class/Reference/Reference.html#//apple_ref/doc/uid/20000050-482446">IMP</a></code>, or function pointer to the method implementation. This function pointer can then be cast to a function pointer with the correct return type, and called to acquire the current value of the attribute in question.</p>
<p><strong>Note:</strong> there are some limitations to this approach. In particular, it shortcuts certain dynamic method look-up behaviours. It will not work if the object being bound to (the binding target) is a proxy, and it will not notice if the object’s class changes, or the class’s method table changes. Such changes are made by the key-value observation mechanism used for normal Cocoa bindings. This doesn’t matter in Oolite, and probably won’t matter in the KVO case either, but it is important to be aware of it.</p>
<pre class="objc-code">- (BOOL)setBindingTarget:(id)target selector:(SEL)selector
{
    NSMethodSignature       *signature;
    IMP                     method;
    unsigned                argCount;
    ShaderUniformType       type;

    if (target == nil)  return NO;
    if (![target respondsToSelector:selector])  return NO;

    // Get the IMP
    method = [target methodForSelector:selector];
    if (method == NULL)  return NO;

    // Get the method signature
    signature = [target methodSignatureForSelector:selector];
    if (signature == nil)  return NO;

    // All methods have two implicit arguments: self and _msg.
    // Getters have no explicit arguments and therefore have
    // a total of two arguments.
    argCount = [signature numberOfArguments];
    if (argCount != 2)  return NO;

    type = ShaderUniformTypeFromMethodSignature(signature);
    if (type == kShaderUniformTypeInvalid)  return NO;

    // All tests passed – binding is complete.
    _target = target;
    _selector = selector;
    _method = method;
    _type = type;
}

typedef float (*FloatReturnMsgSend)(id, SEL);

- (void)apply
{
    switch (_type)
    {
        case kShaderUniformTypeFloat:
            float fValue = ((FloatReturnMsgSend)_method)(_target, _selector);
            glUniform1fARB(_location, fValue);
            break;

        // Handle other types
        …
    }
}</pre>
<h3>But, er… what is it?</h3>
<p>The only non-standard thing in the above is the function <code>ShaderUniformTypeFromMethodSignature()</code>. It takes an <code><a title="NSMethodSignature Class Reference – Apple Developer Connection" href="http://developer.apple.com/documentation/Cocoa/Reference/Foundation/Classes/NSMethodSignature_Class/Reference/Reference.html#//apple_ref/doc/c_ref/NSMethodSignature">NSMethodSignature</a></code> and returns an <code>enum</code> specifying the return type of the accessor method we are binding to. The method <code>-[NSMethodSignature <a title="NSMethodSignature Class Reference – Apple Developer Connection" href="http://developer.apple.com/documentation/Cocoa/Reference/Foundation/Classes/NSMethodSignature_Class/Reference/Reference.html#//apple_ref/occ/instm/NSMethodSignature/methodReturnType"> methodReturnType</a>]</code> exists for this very purpose. However, this is the source of the aforementioned complication. Cocoa’s implementation returns what you might expect: the <code>@encode()</code> string corresponding to the method’s return type. Therefore, the initial implementation of <code>ShaderUniformTypeFromMethodSignature()</code> in Oolite looked like this:</p>
<pre class="objc-code">ShaderUniformType ShaderUniformTypeFromMethodSignature(NSMethodSignature *sig)
{
    const char *type = [sig methodReturnType];
    if (type == NULL)  return kShaderUniformTypeInvalid;

    if (strcmp(type, @encode(float)) == 0)  return kShaderUniformTypeFloat;
    // Handle other types
    …
    else return  kShaderUniformTypeInvalid;
}</pre>
<p>However, as the astute reader may have guessed, this did not work under GNUstep. Assiduous link-followers will be quick to point out that the documentation clearly states, “This encoding is implementation-specific, so applications should use it with caution.” In fact, GNUstep seems to return an encoding string for the entire method, that is, the encoding of all the arguments as well as the return type. (I maintain that this is a bug, since it returns different strings for <code>-(int)foo</code> and <code>-(int)bar:(id)frob</code>. However, since we’re only interested in methods with no explicit arguments, that doesn’t matter.) More importantly to the Cocoa programmer, this statement in the documentation means Apple is free to change the Cocoa implementation at any time.</p>
<p>Fortunately, there’s a simple solution: compare to the <code>methodReturnType</code>s of known methods that return the required type. The final implementation uses a template class which implements a method for each required return type and copies the <code>methodReturnType</code>s of these methods into an array. The template class pattern may be familiar if you’ve written <code>NSProxy</code>s.</p>
<h3>Free code!</h3>
<p>Oolite’s code is complicated. The code given above is too simple. So here’s some code that’s just right.</p>
<p>The sample application uses a stripped-down version of the shader code from Oolite. It presents a scene consisting of a ball with per-pixel lighting and two moving lights, and controls to set two properties, colour and shininess (a combination of specular exponent and specular intensity). The window controller (cleverly named <code>ExampleController</code>) moves the lights about on a timer.</p>
<p class="imgcaption"><a href="http://jens.ayton.se/blag/wp-content/uploads/2007/07/uniform-bindings-1.png"><img src="http://jens.ayton.se/blag/wp-content/uploads/2007/07/uniform-bindings-1.thumbnail.png" border="0" height="104" width="128" alt="A screen shot of the demo application." /></a>&nbsp;<br />
<a href="http://jens.ayton.se/blag/wp-content/uploads/2007/07/uniform-bindings-2.png"><img src="http://jens.ayton.se/blag/wp-content/uploads/2007/07/uniform-bindings-2.thumbnail.png" border="0" height="104" width="128" alt="A screen shot of the demo application." /></a><br clear="all" /><br />
The demo application.</p>
<p>The controls do not affect the scene directly; their values are stored in a model object (<code>ExampleModel</code>) which knows nothing of OpenGL, shaders or lighting. The OpenGL view (<code>ExampleOpenGLView</code>) sets up a shader material and binds the uniforms <code>uColor</code> and <code>uShininess</code> to the appropriate model properties:</p>
<pre class="objc-code">_material = [[JAShaderMaterial alloc] initWithVertexShaderSource:vertSource
                                            fragmentShaderSource:fragSource];

// Bind shader uniforms to model attributes.
[_material bindUniform:@"uColor" toObject:_model property:@selector(color)];
[_material bindUniform:@"uShininess" toObject:_model property:@selector(shininess)];</pre>
<p>The material creates <code>JAShaderUniform</code> objects to handle the individual uniforms. Now, whenever the shader is used (specifically, when its <code>-apply</code> method is called), the uniform objects pull in their values from the model object. When the slider is moved, the model’s <code>shininess</code> value is changed; when the scene next redraws, the shader’s <code>uShininess</code> uniform reflects the new value. The controller and view don’t need to do anything to update them.</p>
<h3>Limitations</h3>
<p>The sample app, being a sample app, glosses over some issues. For one thing, binding targets are not retained, to avoid retain cycles. This is the Right Thing when the binding target is the owner of the material, but if it isn’t, you may inadvertently release an object which is bound to. Oolite avoids this by using a proxy-based weak reference system, which is beyond the scope of this article. The sample app also doesn’t bother to check whether its OpenGL context actually supports shaders.</p>
<p>However, the uniform implementation is pretty complete. It supports most of the types Oolite does, namely:</p>
<ul>
<li> Signed and unsigned <code>char</code>s, <code>short</code>s and <code>long</code>s</li>
<li> <code>float</code>s and <code>double</code>s</li>
<li> Vectors, in the form of <code>JAVector</code> structs. In real life, you’d want to use whatever vector struct or class you use for the rest of your application.</li>
<li> <code>NSPoint</code>s (as <code>vec2</code>s)</li>
<li> <code>NSNumber</code>s (as <code>float</code>s)</li>
<li> <code>NSColor</code>s (as <code>vec4</code>s)</li>
</ul>
<p>One Oolite feature removed for the example is filtering. Filters supported by Oolite include clamping numbers to the range 0..1, normalizing vectors, and converting quaternions to rotation matrices. These are simple operations that aren’t relevant to the focus of this article.</p>
<p>The sample code may be downloaded <a href="http://jens.ayton.se/code/files/glslbindings.zip">here</a> (99 kB) and is distributed under the <a title="The MIT License – Open Source Initiative" href="http://www.opensource.org/licenses/mit-license.php">MIT/X11 License</a>.</p>
<h3>Disclaimer</h3>
<p>Some of the above is not true. Some is misremembered. Some is glossed over and simplified. The code extracts are all simplified, untested code. Caveat lector.</p>
]]></content:encoded>
			<wfw:commentRss>http://jens.ayton.se/blag/glsl-uniform-bindings-for-cocoa/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

