Saturday, January 30, 2010

Getting Started with F# and OpenGL on OS X

I am exploring programming with F# using mono on OS X. I'm thinking about using F# for a computer vision project and so I wanted to start out by playing around with some example code to see how it all works. This post is just to document the steps to get up and running. I'm a complete newbie to F# and mono so please give feedback if there are better ways to go about what I'm doing. I'd also like to eventually have a build environment that works well with mono on OS X and MS Visual Studio. Please leave a comment if you have any advice on this.
  • Initially I installed mono 2.6.1. using the OS X Intel installer which worked without any issues.
  • Next I downloaded and unzipped the F# 1.9.7.8 zip file from the F# downloads page. The zip file contains a convenient install-mono.sh script so all you have to do is
    chmod +x install-mono.sh && sudo ./install-mono.sh
  • I decided to create bash scripts for the compiler and interpreter just for the sake of convenience:
    mv FSharp-1.9.7.8 ~/bin/
    The contents of ~/bin/fsc.bash:
    #!/bin/bash
    
    mono `dirname $0`/FSharp-1.9.7.8/bin/fsc.exe "$@"
    
    ... and likewise the contents of ~/fsi.bash:
    #!/bin/bash
    
    mono `dirname $0`/FSharp-1.9.7.8/bin/fsi.exe "$@"
    
OK great, we now have a working F# compiler and interpreter on OS X (make sure that ~/bin is on your $PATH though... you already knew that didn't you?). OK now let's try to work with one of the F# Samples to make sure things are working as expected. We can build and run the Samples101 example with this command:
fsc.bash --resource:SampleForm.resx \
    sample.fs sampleform.fs Beginners.fs \
    intermediate.fs program.fs
mono program.exe

hmm... almost there. It looks like there is a hard-coded "..\..\" that gets inserted in source code path. A minor code change in sample.fs fixes that:
60c60,61
<         let dir = System.IO.Path.Combine(appdir, @"..\..\")
---
>         //let dir = System.IO.Path.Combine(appdir, @"..\..\")
>         let dir = appdir
... now for a second try:

That's better. OK, now let's see about getting an OpenGL example running.
  • First I downloaded the TAO Framework (version 2.1.0) which provides .NET bindings to OpenGL and other API's for gaming
  • You can install all of the libraries into mono's global registry by:
    cd $TAO_HOME/bin
    for file in *.dll; do sudo gacutil -i $file; done
    hmm, I get the following error while trying to install FreeType:
    Installed Tao.FreeType.dll into the gac (/Library/Frameworks/Mono.framework/Versions/2.6.1/lib/mono/gac)
    
    ** (/Library/Frameworks/Mono.framework/Versions/2.6.1/lib/mono/2.0/gacutil.exe:253): WARNING **:
    Error parsing  \x87\xa0: Error on line 3 char 46: 'libglfw.so"' is not a valid name: '"'
    I'm going to ignore this for now since it doesn't seem to matter for my simple example code.
OK now let's translate the simplest TAO example to F# and see about getting it to run. This is a translation of the $TAO_HOME/source/examples/Redbook/Hello.cs example which is under the MIT License (see license text at end of post). Apologies for the lack of syntax hilighting:
open System
open Tao.FreeGlut
open Tao.OpenGl

let init () =
    // Select clearing color
    Gl.glClearColor (0.0f, 0.0f, 0.0f, 0.0f);

    // Initialize viewing values
    Gl.glMatrixMode Gl.GL_PROJECTION;
    Gl.glLoadIdentity ();
    Gl.glOrtho (0.0, 1.0, 0.0, 1.0, -1.0, 1.0)

let display () =
    // Clear all pixels.
    Gl.glClear Gl.GL_COLOR_BUFFER_BIT;

    // Draw white polygon (rectangle) with corners at (0.25, 0.25, 0.0) and
    // (0.75, 0.75, 0.0).
    Gl.glColor3f (1.0f, 1.0f, 1.0f);
    Gl.glBegin Gl.GL_POLYGON;
        Gl.glVertex3f (0.25f, 0.25f, 0.0f);
        Gl.glVertex3f (0.75f, 0.25f, 0.0f);
        Gl.glVertex3f (0.75f, 0.75f, 0.0f);
        Gl.glVertex3f (0.25f, 0.75f, 0.0f);
    Gl.glEnd ();

    // Don't wait!  Start processing buffered OpenGL routines.
    Gl.glFlush ()

// Declares initial window size, position, and display mode (single buffer and
// RGBA).  Open window with "Hello" in its title bar.  Call initialization
// routines.  Register callback function to display graphics.  Enter main loop
// and process events.
let main =
    Glut.glutInit ();
    Glut.glutInitDisplayMode (Glut.GLUT_SINGLE ||| Glut.GLUT_RGB);
    Glut.glutInitWindowSize (250, 250);
    Glut.glutInitWindowPosition (100, 100);
    ignore (Glut.glutCreateWindow "Hello");
    init ();
    Glut.glutDisplayFunc (new Glut.DisplayCallback(display));
    Glut.glutMainLoop ()

[<STAThread>]
do main
Now I just compile and run with:
fsc.bash -I $TAO_HOME/bin -r Tao.OpenGl.dll -r Tao.FreeGlut.dll hello.fs
mono hello.exe
Hey, it works! That wasn't so painful.
MIT License Copyright 2003-2005 Tao Framework Team http://www.taoframework.com All rights reserved. Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

Sunday, January 10, 2010

Simple Recipe for Static Domain Hosting With Blog

Hopefully this post will help save someone time looking for similar hosting. My current hosting requirements are really simple. I need:
  • static site hosting for keithsheppard.name
  • blog hosting for blog.keithsheppard.name
Luckily blogger lets you use your own domain which takes care of blog.keithsheppard.name so I just need to find a static hosting service for keithsheppard.name. When I went looking for hosting though almost everything I found allows you to run at least PHP, perl scripts along with a MySQL database and costs $5/month or more. Using these hosts means that you have to pay for the extra resources, security and maintenance that goes along with allowing scripts and DB's to run. Another problem is that the cheaper services are often under-resourced which means added down time for you.

After a lot of trial and error I found hurricane electric $1/month static site hosting which has just worked with no problems worth mentioning. As a bonus you transfer your files using scp instead of the lame web-based file managers a lot of the other hosts make you use. HE also throws in a free domain name but I have my domain under dotster and I like keeping the hosting and name registration separate (that costs me an extra $15/year). So for what it's worth, this configuration has worked well for me.


UPDATE: It seems that hurricane electric is no longer advertising $1/month hosting, but no worries I found something better! You can host static content on your domain for free using github (I think something similar is possible with bitbucket). You can find instructions at http://pages.github.com/ and see my example site repo at https://github.com/keithshep/keithshep.github.com (note the CNAME file in my repo).