<?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>silvermace.com &#187; Business as usual</title>
	<atom:link href="http://silvermace.com/category/business-as-usual/feed/" rel="self" type="application/rss+xml" />
	<link>http://silvermace.com</link>
	<description>Danushka &#34;silvermace&#34; Abeysuriya</description>
	<lastBuildDate>Thu, 08 Dec 2011 00:36:40 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.2.1</generator>
		<item>
		<title>Understanding EXT_separate_shader_objects (OpenGLES 2.0.x)</title>
		<link>http://silvermace.com/2011/11/understanding-ext_separate_shader_objects-opengles-2-0-x/</link>
		<comments>http://silvermace.com/2011/11/understanding-ext_separate_shader_objects-opengles-2-0-x/#comments</comments>
		<pubDate>Fri, 25 Nov 2011 04:09:11 +0000</pubDate>
		<dc:creator>Danushka</dc:creator>
				<category><![CDATA[Business as usual]]></category>

		<guid isPermaLink="false">http://silvermace.com/?p=177</guid>
		<description><![CDATA[Traditionally, an OpenGLES shader-program (SP) consisted of 2 shader-objects (SO) precisely one vertex shader and one fragment shader which get attached and linked into some GPU executable format, if either SO is missing or invalid the SP can&#8217;t be used. More annoyingly, in many situations a common vertex shader is used in combination with different fragment shaders, [...]]]></description>
			<content:encoded><![CDATA[<p>Traditionally, an OpenGLES shader-program (SP) consisted of 2 shader-objects (SO) precisely one vertex shader and one fragment shader which get attached and linked into some GPU executable format, if either SO is missing or invalid the SP can&#8217;t be used. More annoyingly, in many situations a common vertex shader is used in combination with different fragment shaders, but a program must exist for each unique pair of VPs and FPs.</p>
<p>This new extension in its current form allows two new changes that relax this requirement to make re-use and organisation of shaders at runtime easier for developers, to paraphrase the spec it allows developers to &#8220;mix-and-match&#8221; stages to create more flexible shader pipelines.</p>
<h2>Seperable Programs</h2>
<p>The first change is that a SP doesn&#8217;t need to have both vertex &amp; fragment shaders bound at link time for it to be considered valid, however this means that an SP that only has either a vertex shader or fragment shader bound (and not both) may not be consdered &#8220;complete&#8221; in a semantic sense; as-per the spec, using a SP that is missing a stage will produce results that are undefined for the missing stages. </p>
<p>Setting a SP to be &#8220;seperable&#8221; is done by setting it&#8217;s GL_PROGRAM_SEPARABLE_EXT parameter to GL_TRUE (just before linking):</p>
<blockquote><p>glProgramParameteriEXT( shaderProgramId, GL_PROGRAM_SEPARABLE_EXT, GL_TRUE );</p></blockquote>
<p>otherwise the SP object behaves as per the unextended spec, i.e. both the vertex and fragment stages must be specified before linking the SP.</p>
<p><em>SIDE NOTE: The glCreateShaderProgramvEXT API is provided to greatly reduce boilerplate and simplifies creation of a seperable shader, and should be your preferred way of creating seperable SP&#8217;s.</em></p>
<h2>Program Pipeline Object</h2>
<p>The second offering of this extension is the Program Pipeline Object (PPO). After linking a set of SP&#8217;s these are consolidated and named by a PPO to allow you to bind a permutation of SP&#8217;s using one named OpenGL object &#8211; the PPO. The PPO also allows uniforms to be set while bypassing the currently bound program object. The <em>glProgramUniform</em>* set  of functions take a PPO name as an argument, and the program to apply the uniform to.</p>
<h2>GLSL level attribute binding</h2>
<p>Supplemental improvements to the GLSL model included in this extension are the ability to set (and override application set) vertex attribute stream locations in GLSL source text. Without this extension, developers currently have to know the attribute identifier used in GLSL code to correctly bind it at runtime e.g.:</p>
<pre style="font-size: 7pt;"><code>// GLSL code:
attribute vec4 myPostion;
attribute vec3 myNormal;
void main() { ... }

// Application Code:
const int POSITION_ATTRIB_INDEX = 0;
const int NORMAL_ATTRIB_INDEX = 1;
...
glBindAttribLocation( prog, POSITION_ATTRIB_INDEX, "myPosition" );
glBindAttribLocation( prog, NORMAL_ATTRIB_INDEX, "myNormal" );
...
glVertexAttribPointer( POSITION_ATTRIB_INDEX, ... )
glVertexAttribPointer( NORMAL_ATTRIB_INDEX, ... )
...
</code></pre>
<p>When the <em>EXT_seperate_shader_objects</em> extension is available, the location index can be specified in shader source text, and also takes precedence over any <em>glBindAttribLocation</em> calls in application code, the above code is simplified by not needing the <em>glBindAttribLocation</em> calls and few changes in the GLSL text e.g.:</p>
<pre style="font-size: 7pt;"><code>// GLSL code:
#extension GL_EXT_separate_shader_objects : enable
layout(location = 0) attribute vec4 myPostion;
layout(location = 1) attribute vec3 myNormal;
void main() { ... }

// Application Code:
const int POSITION_ATTRIB_INDEX = 0;
const int NORMAL_ATTRIB_INDEX = 1;
...
glVertexAttribPointer( POSITION_ATTRIB_INDEX, ... )
glVertexAttribPointer( NORMAL_ATTRIB_INDEX, ... )
...
</code></pre>
<p>The main caveat to this is while is simplifies application code, developers will need to be consistent across several shader files for attribute location binding, though this isn&#8217;t hard and any conflicting layout(location) indexes will cause a GLSL-linker error.</p>
<h2>Example Usage (C++)</h2>
<pre style="font-size: 7pt;"><code>const GLchar* VertexProgramCode =
{
  //tell the driver we need to enable particular GLSL extensions
  //note that the \n is important here
  "#extension GL_EXT_separate_shader_objects : enable\n" 

  //use the layout(location) syntax extension
  "layout(location = 0) attribute vec4 position;"
  "uniform mat4 mvp;"
  "uniform vec4 custom_color;"
  "varying lowp vec4 color;"

  "void main() {"
  "  color = custom_color;"
  "  gl_Position = mvp * position;"
  "}"
};

const GLchar* FragmentProgramCode =
{
  "varying lowp vec4 color;"
  "void main() {"
  "  gl_FragColor = color;"
  "}"
};

class Effect
{
protected:
  void log_status(GLuint prog)
  {
    int len(0);
    const bool is_ppo(glIsProgramPipelineEXT(prog) == GL_TRUE);
    //if this looks odd, it's just an ternary function pointer select
    (is_ppo ? glGetProgramPipelineivEXT : glGetProgramiv)(prog, GL_INFO_LOG_LENGTH, &#038;len);
    if( len > 0 ) {
      GLchar log[len];//gcc extension: non-const array size
      (is_ppo ? glGetProgramPipelineInfoLogEXT : glGetProgramInfoLog)(prog, len, &#038;len, log);
      std::cerr << log << "\n";
    }
  }

  GLuint m_vp;
  GLuint m_fp;
  GLuint m_ppo;

  //vertex program variable locations
  GLint m_mvp_location;
  GLint m_custom_color_location;

public:
  float m_mvp[16];
  float m_custom_color[4];

  Effect() : m_vp(0), m_fp(0), m_ppo(0)
  {
    //identity
    for(int i=0; i<16; ++i)
      m_mvp[i] = (i%5==0)?1.0f:0.0f;

    //default to red
    m_custom_color[0] = 1;
    m_custom_color[1] = 0;
    m_custom_color[2] = 0;
    m_custom_color[3] = 1;
  }

  ~Effect() {
    unload_all();
  } 

  bool load_shaders()
  {
    //in a well designed system you would pick these out of an e.g. vertex/fragment effect pool
    m_vp = glCreateShaderProgramvEXT(GL_VERTEX_SHADER, 1, &#038;VertexProgramCode);
    log_status( m_vp );

    //bind the vertex program variables we need
    m_mvp_location = glGetUniformLocation( m_vp, "mvp");
    m_custom_color_location = glGetUniformLocation( m_vp, "custom_color");
    assert(m_mvp_location > -1);
    assert(m_custom_color_location > -1);

    m_fp = glCreateShaderProgramvEXT(GL_FRAGMENT_SHADER, 1, &#038;FragmentProgramCode);
    log_status( m_fp );

    //generate and construct our PPO
    glGenProgramPipelinesEXT(1, &#038;m_ppo);  

    //this is where you would "mix-and-match" using the bitmask
    //in the 2nd parameter
    glUseProgramStagesEXT(m_ppo, GL_VERTEX_SHADER_BIT_EXT, m_vp);
    glUseProgramStagesEXT(m_ppo, GL_FRAGMENT_SHADER_BIT_EXT, m_fp);

    glValidateProgramPipelineEXT(m_ppo);
    log_status( m_ppo );

    int status(0);
    glGetProgramPipelineivEXT(m_ppo, GL_VALIDATE_STATUS, &#038;status);
    if( status == 0 )
      std::cerr << "unable to create program pipeline\n";
    return status != 0;
  }

  void unload_all()
  {
    glUseProgram(0);
    glBindProgramPipelineEXT(0);
    glDeleteProgramPipelinesEXT(1, &#038;m_ppo);
    glDeleteProgram(m_vp);
    glDeleteProgram(m_fp);
  }

  void bind_pipeline()
  {
    assert(m_ppo);
    glBindProgramPipelineEXT(m_ppo);
    glProgramUniformMatrix4fvEXT(m_vp, m_mvp_location, 1, 0, &#038;m_mvp[0]);
    glProgramUniform4fvEXT(m_vp, m_custom_color_location, 1, &#038;m_custom_color[0]);
  }
};
</code></pre>
]]></content:encoded>
			<wfw:commentRss>http://silvermace.com/2011/11/understanding-ext_separate_shader_objects-opengles-2-0-x/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>XCode Header Path Confusion</title>
		<link>http://silvermace.com/2011/03/xcode-header-path-confusion/</link>
		<comments>http://silvermace.com/2011/03/xcode-header-path-confusion/#comments</comments>
		<pubDate>Fri, 25 Mar 2011 21:40:37 +0000</pubDate>
		<dc:creator>Danushka</dc:creator>
				<category><![CDATA[Business as usual]]></category>

		<guid isPermaLink="false">http://silvermace.com/?p=117</guid>
		<description><![CDATA[XCode&#8217;s search rules for header paths are a strange beast. The most obvious aspects to take into consideration: Correct SDK root &#8220;Header Search Paths&#8221; (Project Settings) &#8220;User Header Search Paths&#8221; (Project Settings) &#8220;Always search user headers&#8221; (Project Settings) But there is one more element that will throw a spanner-of-confusing-impending-doom into the works: Header Maps. This nifty and [...]]]></description>
			<content:encoded><![CDATA[<p>XCode&#8217;s search rules for header paths are a strange beast. The most obvious aspects to take into consideration:</p>
<ul>
<li>Correct SDK root</li>
<li>&#8220;Header Search Paths&#8221; (Project Settings)</li>
<li>&#8220;User Header Search Paths&#8221; (Project Settings)</li>
<li>&#8220;Always search user headers&#8221; (Project Settings)</li>
</ul>
<p>But there is one more element that will throw a spanner-of-confusing-impending-doom into the works: Header Maps.</p>
<p>This <em>nifty</em> and <strong><em>undocumented </em></strong>feature is basically a dictionary of all the filenames in your project (just the filename, not a fully qualified path), supposedly to speed up building, but it definitely gets in the way (in a big way) sometimes.</p>
<p>To keep a long story really short, if your build looks like the header search paths are very confused for example #include &lt;math.h&gt; actually includes a file in your project named Math.h regardless of folder depth that resides somewhere in your project (you can check this using  &#8221;Build&#8221; &gt; &#8220;Preprocess&#8221; and check which files its actually #included&#8217;ed)</p>
<p>Project &gt; Edit Project Settings &gt; (Cog Button Bottom Left) &gt; Add User-Defined Setting</p>
<p>Name the setting <strong>USE_HEADERMAP </strong>and set its value to <strong>NO </strong>(EDIT 24/11/11: this was incorrectly USE_HEADERMAP<em>S &#8211; should not be plural, thanks Simon for pointing this out)</em></p>
<p>Now all header includes MUST be relative to the file they are included from OR be explicitly relative from any of your specified header search paths.</p>
<p>More reading provided below:</p>
<p><a href="http://web.archiveorange.com/archive/v/JT06F65y3o5h2vjWtjBo">http://web.archiveorange.com/archive/v/JT06F65y3o5h2vjWtjBo</a></p>
<p><a href="http://web.archiveorange.com/archive/v/JT06F65y3o5h2vjWtjBo"></a><a href="http://www.openradar.me/7840694">http://www.openradar.me/7840694</a></p>
<p><a href="http://www.omnigroup.com/mailman/archive/macosx-dev/2005-March/056049.html">http://www.omnigroup.com/mailman/archive/macosx-dev/2005-March/056049.html</a></p>
<p><a href="http://stackoverflow.com/questions/2596695/controlling-which-project-header-file-xcode-will-include">http://stackoverflow.com/questions/2596695/controlling-which-project-header-file-xcode-will-include</a></p>
<p>Excuse the keyword dump here, it was hard to find this out so I hope this will help others looking:<br />
cannot find correct system headers, header path order, include path order, search path order, Xcode include file quotes, header maps, hmap, import directive, include confused, incorrect include search path</p>
]]></content:encoded>
			<wfw:commentRss>http://silvermace.com/2011/03/xcode-header-path-confusion/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Finding UID&#8217;s in MacOS X 10.5/10.6</title>
		<link>http://silvermace.com/2010/03/finiding-uids-in-macos-x-105106/</link>
		<comments>http://silvermace.com/2010/03/finiding-uids-in-macos-x-105106/#comments</comments>
		<pubDate>Wed, 10 Mar 2010 23:50:46 +0000</pubDate>
		<dc:creator>Danushka</dc:creator>
				<category><![CDATA[Business as usual]]></category>

		<guid isPermaLink="false">http://www.silvermace.com/?p=86</guid>
		<description><![CDATA[Was helping setup a VM/NFS share on a friends OSX machine using all_squash to remap the UID and GID. Unfortunately OSX doesn&#8217;t like using the /etc/group file as traditional linux, doesn&#8217;t provide uid and gid commands or the Netinfo utility. So to cut to the chase, to list the UIDs of the local users: dscl [...]]]></description>
			<content:encoded><![CDATA[<p>Was helping setup a VM/NFS share on a friends OSX machine using all_squash to remap the UID and GID. Unfortunately OSX doesn&#8217;t like using the /etc/group file as traditional linux, doesn&#8217;t provide uid and gid commands or the Netinfo utility. So to cut to the chase, to list the UIDs of the local users:</p>
<p><code>dscl /Local/Default -list /Users UniqueID</code></p>
<p>I&#8217;m sure altering the last &#8220;UniqueID&#8221; value (as it&#8217;s referred to as a &#8216;key&#8217;) will yeild more interesting info, this is left as an excercise to the reader <img src='http://silvermace.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
]]></content:encoded>
			<wfw:commentRss>http://silvermace.com/2010/03/finiding-uids-in-macos-x-105106/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Postfix SMTPD with SASL and AUTHMYSQL</title>
		<link>http://silvermace.com/2010/01/postfix-smtpd-with-sasl-and-authmysql/</link>
		<comments>http://silvermace.com/2010/01/postfix-smtpd-with-sasl-and-authmysql/#comments</comments>
		<pubDate>Thu, 07 Jan 2010 07:17:34 +0000</pubDate>
		<dc:creator>Danushka</dc:creator>
				<category><![CDATA[Business as usual]]></category>

		<guid isPermaLink="false">http://www.silvermace.com/?p=81</guid>
		<description><![CDATA[Setting up Postfix can be a bit of a jungle of information, I was left scratching my head wondering why Postfix refused to relay an email to an external address even when provided valid user credentials. The issue seemed to be that Postfix SMTPD wasn&#8217;t paying any attention to the /etc/postfix/sasl/smtpd.conf file (which contained the [...]]]></description>
			<content:encoded><![CDATA[<p>Setting up Postfix can be a bit of a jungle of information, I was left scratching my head wondering why Postfix refused to relay an email to an external address even when provided valid user credentials. The issue seemed to be that Postfix SMTPD wasn&#8217;t paying any attention to the /etc/postfix/sasl/smtpd.conf file (which contained the auxprop mysql authentication plugin configuration) and hence was falling back to its default PAM based system.</p>
<p>The fix was the most paintfully simple addition to the Postfix main.cf, highlighted bold. This fix seems to only apply to Ubuntu based environments and means that the smtpd daemon will actually pay attention to the contents of /etc/postfix/sasl/smtpd.conf</p>
<p><code>smtpd_sasl_auth_enable = yes<br />
smtpd_sasl_security_options = noanonymous<br />
smtpd_sasl_local_domain = $myhostname<br />
<em><strong>smtpd_sasl_application_name = smtpd</strong></em><br />
broken_sasl_auth_clients = yes<br />
</code></p>
<p>more reading: <a href="http://ubuntuforums.org/showthread.php?t=297462">http://ubuntuforums.org/showthread.php?t=297462</a></p>
]]></content:encoded>
			<wfw:commentRss>http://silvermace.com/2010/01/postfix-smtpd-with-sasl-and-authmysql/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Handy VC2008 Macro</title>
		<link>http://silvermace.com/2009/11/handy-vc2008-macro/</link>
		<comments>http://silvermace.com/2009/11/handy-vc2008-macro/#comments</comments>
		<pubDate>Fri, 27 Nov 2009 23:34:56 +0000</pubDate>
		<dc:creator>Danushka</dc:creator>
				<category><![CDATA[Business as usual]]></category>

		<guid isPermaLink="false">http://www.silvermace.com/?p=79</guid>
		<description><![CDATA[So, if you&#8217;ve ever tried to drag a folder from the filesystem into VS Solution Explorerer, sure it&#8217;ll recursively add all the files, but it wont mirror the folders in the solution, so you end up with every file placed at the root level of whatever &#8220;filter-folder&#8221; you dragged it into. This is very annoying [...]]]></description>
			<content:encoded><![CDATA[<p>So, if you&#8217;ve ever tried to drag a folder from the filesystem into VS Solution Explorerer, sure it&#8217;ll recursively add all the files, but it wont mirror the folders in the solution, so you end up with every file placed at the root level of whatever &#8220;filter-folder&#8221; you dragged it into. This is very annoying when you have a project with say ~1,500 files.</p>
<p>I thought about how I could get around this and have the Solution Explorer folders mirror the filesystem, first obvious option was write a shell script or macro to do it. So I fired up VS macro explorer and lo-and-behold theres a Sample macro which ships with VS called &#8220;AddDirAsSlnFolder&#8221;.</p>
<p>Looking very promising I checked out the source code, and sure enough it does exactly what I needed. The only thing I had to do to get it working exactly right was add &#8220;.svn&#8221; to the exclusions list (this is down the bottom of the source file and should be clearly visible next to all the other exclusions in the list)</p>
<p>Enjoy.</p>
]]></content:encoded>
			<wfw:commentRss>http://silvermace.com/2009/11/handy-vc2008-macro/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Getting FCollada to compile with VC++ 2008</title>
		<link>http://silvermace.com/2009/07/getting-fcollada-to-compile-with-vc-2008/</link>
		<comments>http://silvermace.com/2009/07/getting-fcollada-to-compile-with-vc-2008/#comments</comments>
		<pubDate>Tue, 28 Jul 2009 00:41:25 +0000</pubDate>
		<dc:creator>Danushka</dc:creator>
				<category><![CDATA[Business as usual]]></category>

		<guid isPermaLink="false">http://www.silvermace.com/?p=73</guid>
		<description><![CDATA[When trying to build from the converted VC2005 solution file, you will encounter quite a few errors regarding mismatching declaration of _vsnprintf. error C3163: '_vsnprintf': attributes inconsistent with previous declaration the last post in this thread clarifies how this error arrises in common practice. To get it to compile I commented out these lines: FUtils\Platforms.h:145 [...]]]></description>
			<content:encoded><![CDATA[<p>When trying to build from the converted VC2005 solution file, you will encounter quite a few errors regarding mismatching declaration of _vsnprintf.</p>
<p><code>error C3163: '_vsnprintf': attributes inconsistent with previous declaration</code></p>
<p>the last post in <a href="http://social.msdn.microsoft.com/Forums/en-US/vsexpress2008installationandsetup/thread/24f0a7d9-d068-41f0-8827-fef35cd545de">this thread</a> clarifies how this error arrises in common practice. To get it to compile I commented out these lines:</p>
<ul>
<li> FUtils\Platforms.h:145</li>
<li>LibXML\config.h:92</li>
<li>LibXML\include\win32config.h:90</li>
<li>DLLEntry:40 (this one was just a missing symbol or something deprecated in new the PSDK shipping with VC9, the case statement is empty so commenting it out should have no effect)</li>
</ul>
<p>I should clearly note that I haven&#8217;t tested it (running etc.), I simply got it to build to help save our tools guy a bit of time. I should also note that the Unit Tests (FColladaTest) project builds but returns about 60 linker errors. I just thought I&#8217;d post here to save someone a bit of hassle if they should run into this error.</p>
<p>FCollada version was 3.05B Win32</p>
<p>-Danu</p>
]]></content:encoded>
			<wfw:commentRss>http://silvermace.com/2009/07/getting-fcollada-to-compile-with-vc-2008/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>fun with numeric_limits min</title>
		<link>http://silvermace.com/2009/06/fun-with-numeric_limits-min/</link>
		<comments>http://silvermace.com/2009/06/fun-with-numeric_limits-min/#comments</comments>
		<pubDate>Sun, 21 Jun 2009 01:17:12 +0000</pubDate>
		<dc:creator>Danushka</dc:creator>
				<category><![CDATA[Business as usual]]></category>

		<guid isPermaLink="false">http://www.silvermace.com/?p=66</guid>
		<description><![CDATA[Just a quick note, I thought others might find this helpful as well. In our level compiler, a bug which somehow went un-noticed for a little while was causing bounding boxes to not be calculated properly. This turned out to be a simple initialization oversight. Vec3 maxValue, minValue; ofcourse the default constructor would initialize both [...]]]></description>
			<content:encoded><![CDATA[<p>Just a quick note, I thought others might find this helpful as well. In our level compiler, a bug which somehow went un-noticed for a little while was causing bounding boxes to not be calculated properly. This turned out to be a simple initialization oversight.</p>
<p><code>Vec3 maxValue, minValue;</code></p>
<p>ofcourse the default constructor would initialize both vectors to [0,0,0]. This is useless when trying to determine a bounding box which lies entirely in the negative part of all axies (because no vertex in that area will ever excede maxValue, which has incorrectly been initalized to zero). The fix was simple, but it reminded me of another C/C++ quirk over numeric limits.</p>
<p>The fix, one would think, would be something like this:</p>
<p><code>const float FLOAT_HIGHEST = std::numeric_limits&lt;float&gt;::max();<br />
const float FLOAT_LOWEST = std::numeric_limits&lt;float&gt;::min();<br />
Vec3 maxValue(FLOAT_HIGHEST, FLOAT_HIGHEST, FLOAT_HIGHEST);<br />
Vec3 maxValue(FLOAT_LOWEST, FLOAT_LOWEST, FLOAT_LOWEST);</code></p>
<p>But, you&#8217;de be wrong. If you were using numeric_limits&lt;int&gt; that would work fine, but numeric_limits&lt;float&gt;::min acutally returns the lowest representable <em>positive</em> float (this is to help calculate another issue with IEEE floats see: <a href="http://en.wikipedia.org/wiki/Denormal">http://en.wikipedia.org/wiki/Denormal</a>).</p>
<p>Boost provides a clean solution for this in their <a href="http://www.boost.org/doc/libs/1_38_0/libs/numeric/conversion/doc/html/boost_numericconversion/bounds___traits_class.html">&#8220;bounds&#8221; package</a>.</p>
<p>I&#8217;m tempted to just go &#8220;-numeric_limits&lt;float&gt;::max()&#8221; (that is pretty much what the boost code will compile down to) but I like consistency, and I don&#8217;t want to worry about any (if any exist?) unmatched upper and lower values like 32 bit signed ints have, I&#8217;m no float expert&#8230;</p>
]]></content:encoded>
			<wfw:commentRss>http://silvermace.com/2009/06/fun-with-numeric_limits-min/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>You live and learn, C++</title>
		<link>http://silvermace.com/2009/04/you-live-and-learn-c/</link>
		<comments>http://silvermace.com/2009/04/you-live-and-learn-c/#comments</comments>
		<pubDate>Wed, 01 Apr 2009 11:57:36 +0000</pubDate>
		<dc:creator>Danushka</dc:creator>
				<category><![CDATA[Business as usual]]></category>

		<guid isPermaLink="false">http://www.silvermace.com/?p=48</guid>
		<description><![CDATA[I&#8217;ve switch jobs and im working with C++, Objective-C++ and alot of cross platform stuff. Which is a nice change of pace from Java.  I&#8217;ve extracted out the C++ unit testing framework from one of our IP projects and am actively using it to write unit test for a data exporter im working with, which [...]]]></description>
			<content:encoded><![CDATA[<p>I&#8217;ve switch jobs and im working with C++, Objective-C++ and alot of cross platform stuff. Which is a nice change of pace from Java.  I&#8217;ve extracted out the C++ unit testing framework from one of our IP projects and am actively using it to write unit test for a data exporter im working with, which brings me to my point for this post. And thanks to Kevin who helped me figure this out.</p>
<p>In C++, it turns out function-call arguments are not guaranteed by the standard to be evaluated in the traditional &#8220;left-to-right&#8221; order. Instead, it&#8217;s totaly implementation defined, and I&#8217;ve found that on VC++ (2k5) its as you would expect about 90% of the time, but there are certain situations where the compiler decides to mix things up.</p>
<p>the problem was noted in this piece of code:</p>
<p>Vec3 boundsMin( reader.readF32(), reader.readF32(), reader.readF32() )</p>
<p>the compiler translated it into something along these lines:</p>
<p>call readF32  /* stores the result in ecx */<br />
push ecx<br />
fstp dword ptr [esp]<br />
call readF32<br />
push ecx<br />
fstp dword ptr [esp]<br />
call readF32<br />
push ecx<br />
fstp dword ptr [esp]<br />
lea [boundsMin]<br />
call Vec3::Vec3</p>
<p>notice how the store instruction &#8220;fstp&#8221; always writes to the memory location specified by esp? now the assembly generated for Vec3 constructor&#8217;s uses the &#8220;rep stos&#8221; instruction to &#8220;block copy&#8221; the contents of the location esp refers to. Initially, all this code looks like it happens how you would expect: &#8220;left-to-right&#8221; but the reason it doesnt work as expected is because the &#8220;push&#8221; instruction is decrementing the value in esp by 4 and writing the value of the operand to the top of the stack every time its called.</p>
<p>What does this mean? in simple terms, yes, the reads happen in the order A,B,C but the resulting values are written into the stack-frame effectively backwards C,B,A (I say effectively because the &#8220;rep stos&#8221; instruction reads from lower memory to higher memory, but C was written to lower memory (because it was written last, hence esp would be at its lowest value), B in higher memory after C and A in even higher memory after B). This is where the non-guaratee by the standard comes into play, the only reason the compiler does this is because there is no requirement to do otherwise. hence all the values for this particular vector were having their x and z values swapped consistently in &#8220;Debug&#8221; generated code.</p>
<p>Fun times.</p>
<p>Oh and the lesson from all this: don&#8217;t inline function argument-expressions which have dependent reads. e.g. reading from streams.</p>
<p>For more reading: <a href="http://compilers.iecc.com/comparch/article/95-07-089">http://www.embedded.com/story/OEG20020429S0037</a><br />
and: <a href="http://compilers.iecc.com/comparch/article/95-07-089">http://compilers.iecc.com/comparch/article/95-07-089</a></p>
]]></content:encoded>
			<wfw:commentRss>http://silvermace.com/2009/04/you-live-and-learn-c/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Relearning C++</title>
		<link>http://silvermace.com/2008/12/relearning-c/</link>
		<comments>http://silvermace.com/2008/12/relearning-c/#comments</comments>
		<pubDate>Sun, 21 Dec 2008 21:52:43 +0000</pubDate>
		<dc:creator>Danushka</dc:creator>
				<category><![CDATA[Business as usual]]></category>

		<guid isPermaLink="false">http://www.silvermace.com/?p=45</guid>
		<description><![CDATA[I haven&#8217;t blogged in a while now, so I thought I&#8217;d write something about a new personal project I&#8217;ve started. I entitled the post &#8220;relearning C++&#8221; because though I know lots of the language quirks and the nitty-gritty of C++, I have considered the past year or so a total re-introduction in the way I [...]]]></description>
			<content:encoded><![CDATA[<p>I haven&#8217;t blogged in a while now, so I thought I&#8217;d write something about a new personal project I&#8217;ve started. I entitled the post &#8220;relearning C++&#8221; because though I know lots of the language quirks and the nitty-gritty of C++, I have considered the past year or so a total re-introduction in the way I <em>apply</em> C++ and in particular, go about developing software using C++. For 10 years now I have used C and C++ in my daily life, being self taught from an early age it has lead to lots of painful (to say the least) learning experiences and I would have to say that up until recently my C++ code has had that &#8220;self taught&#8221; feeling to it &#8211; Most of you know what I mean, mediocre variable names, slightly odd coding styles, choosing brevity over clarity and so forth.</p>
<p>The last few years working with Java in the industry has given me a little bit of insight on producing<em> quality</em> software over software that just does what it&#8217;s supposed to, this is the &#8220;relearning&#8221; I refer to.</p>
<p>The new project has been written in a unit-test centric manner, that&#8217;s not to say its TDD nor has it 99% code coverage, but unit-test are part of the center stage. Additionally, we are making good (not over-the-top) use of the collection of powerful Boost libraries, and using these meta-programming/template heavy libraries has definitely learned me a thing or two about C++ &#8211; I guess that&#8217;s the thing about C++, no matter how long you&#8217;ve been using it effectively, there&#8217;s just so much to know and there are always those &#8220;ahhh-haa [forgot about that!!!]&#8221; moments and I guess for me this makes things a bit more challenging, but a little bit more fun (but probably not as productive as it could be).</p>
<p>I wrote the unit testing framework for our project, quite a simple suite/runner system. The system has been valuable for us as a  2-man-decentralised-after-hours-team (2MDAHT) &#8211; basically self documentation for code and use-cases and full regression testability, which when communication is not as often as we&#8217;d like it, is a great way to make sure we&#8217;re always taking two steps forward and none back.</p>
<p>The system is also written thread-safe from the ground up, the unit tests and our design-test-implement-test  philosophy allow us to see deadlock situations during the design-test phase and then during implementation allow us to more easily replicate and fix deadlocks by drastically narrowing the window of code which could be causing the problem.</p>
<p>If you had asked me 2-3 years ago whether unit-testing C++ code was worth it, I would&#8217;ve almost certainly would have said &#8220;no&#8221; or at best &#8220;it depends&#8221;, today I would go so far as to say it would be a &#8220;must&#8221; (however I do appreciate the feeling of impending doom when faced with retro-fitting legacy C++ for unit testing).</p>
]]></content:encoded>
			<wfw:commentRss>http://silvermace.com/2008/12/relearning-c/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Weve 2.0.3 Beta</title>
		<link>http://silvermace.com/2008/09/weve-203-beta/</link>
		<comments>http://silvermace.com/2008/09/weve-203-beta/#comments</comments>
		<pubDate>Mon, 08 Sep 2008 08:15:22 +0000</pubDate>
		<dc:creator>Danushka</dc:creator>
				<category><![CDATA[Business as usual]]></category>

		<guid isPermaLink="false">http://www.silvermace.com/?p=29</guid>
		<description><![CDATA[After a long absence, I&#8217;ve brought back WEVE (Windows Environment Variable Editor). I use it a lot, and quite a few people got some good use from Weve 1.5. This came about when today I got an email from Robert Hadjiyski asking what ever happened to WEVE, and if I would be able to provide [...]]]></description>
			<content:encoded><![CDATA[<p>After a long absence, I&#8217;ve brought back <a href="http://www.silvermace.com/?page_id=24">WEVE (Windows Environment Variable Editor)</a>. I use it a lot, and quite a few people got some good use from Weve 1.5. This came about when today I got an email from Robert Hadjiyski asking what ever happened to WEVE, and if I would be able to provide the source code so that he may make bug fixes/improvements.</p>
<p>This reminded me that I had Weve 2.0 sitting around on my HDD gathering dust. So I&#8217;ve put the binaries up in a ZIP file, and I have applied to have a source forge page created to host/manage the project&#8217;s source code. At some stage I&#8217;ll update the MSI installer project and stick that version up too.</p>
<p>Hope people like the 2.0 improvements, alot of handy features that make WEVE 2.0 even easier and more intuitive to use than 1.5.</p>
<p>Get it from the <a href="http://www.silvermace.com/?page_id=24">WEVE page</a></p>
]]></content:encoded>
			<wfw:commentRss>http://silvermace.com/2008/09/weve-203-beta/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

