<?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; OpenGL</title>
	<atom:link href="http://jens.ayton.se/blag/tags/code/opengl/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, 15 Jul 2010 09:01:42 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0</generator>
		<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>
