3D Rendering with CFML

As everyone knows, CFML is the perfect language for every sort of programming job.  Including 3D games.  The animation is a little choppy with dynamically generated images having to be streamed down from the server side, but never let technology's shortcomings stand in the way of using your favorite tool.  Unfortunately, I haven't run across any sort of 3D graphics package for CFML, so I started building one.

If you were there at CFUnited a couple weeks back, you saw Ray Camden's awesome maze demo.  I was talking to him afterward and mentioned that it'd be cool if you could walk through the maze in 3D (a la Wolfenstein), instead of just text-only.  Last week I threw together a really simple renderer for maze parts, but it was full of kludges and hackery, so I decided to work on a real engine.

Since we're talking about images here, everything is static.  You're drawing a single frame at a time.  You create a renderer, tell it where the camera is, how it's oriented, what it's field of view is, and then you start drawing your objects.  And and the end, you ask it for the composited image.  All your drawing happen in threespace (x, y, z), and the renderer takes care of all the translation to create the flat image you want.  Here's a sample (a 10×10 grid with a few "wall" segments, and then a hollow red box.  The camera is positioned up and back a little, so you can't see the whole grid, but you get the idea.

block_world

The code looks something like this:

<cfset renderer = createObject("component", "renderer")
  .init(width, height)
  .setCameraPosition(3.5, 1.8, -2)
  .setCameraRotation(0, -10)
  .setColor("009900")
/>
<cfloop from="0" to="10" index="i">
  <cfset renderer.drawLine("#i#,0,0", "#i#,0,10") />
  <cfset renderer.drawLine("0,0,#i#", "10,0,#i#") />
</cfloop>
<cfset renderer
  .setColor("990000")
  .drawPolygon("1,0,1;2,0,1;2,0,2;1,0,2")
  .setColor("ff0000")
  .drawPolygon("1,3,1;2,3,1;2,3,2;1,3,2")
  .setColor("cc0000")
  .drawLine("1,0,1", "1,3,1")
  .drawLine("1,0,2", "1,3,2")
  .drawLine("2,0,1", "2,3,1")
  .drawLine("2,0,2", "2,3,2")
/>

I haven't quite got all the camera orientation stuff worked out right (bad math somewhere), but when that's done and I've created a couple more primitives, I'll be sharing.  After that, I'll probably work on making a stateful model so you can build a model of your world, including referencable and mutable objects, and then take a snapshot of it from an arbitrary location.  Currently it works in reverse (as described above) which makes it WAY easier to code but wastes a lot of CPU time if you have a complex and mostly static world.  If you've been struggling to build a rich 3D experience using CFML without any of those crappy browser plugins (or, horror of horrors, a standalone binary), this could be the ultimate answer.

Just for reference, here's an example of the first (hackey/kludgey) version's output:

rays_maze

The code could is purpose-specific for rendering a view down a hallway and doesn't account for parallel halls or anything else complicated.  This image represents "wdwdwedwdwd", which is interpreted as (W)alls, (D)oors, and the (E)nd of the all, starting at the left, and working around to the right.  It looks way better than it works.  ;)

9 responses to “3D Rendering with CFML”

  1. Sammy Larbi

    Oh, this is absolute brilliance.

    "never let technology's shortcomings stand in the way of using your favorite tool"

    I love it!

  2. Josh Knutson

    Very Very cool, ask the community for help if you need any, just keep blogging about it.

  3. Brad Wood

    Dude, that's kick-butt. It reminds me of openGL. I expect you to have a working Doom map pretty soon. :)

  4. Ben Koshy

    You sir, are nuts! :)

  5. Todd Rafferty

    Barney, this is hilarious. Great job! :)

  6. phill.nacelli

    Barney,

    Madness!!! Madness I say!!! Simply Brilliant dude..

    Cheers..

    PS: It was nice catching up with you at CFUnited..

  7. Gerald Guido

    You sir, are out of your farking mind.

    >>but never let technology's shortcomings stand in the way of using your favorite tool.

    With that said, CF is one hell of a hammer.

  8. Steve Withington

    @Barney, first of all … freakin' cool! secondly, when you think about it, this really should be explored further. considering CF is built on top of Java, and by using Java, we can build some pretty cool games, etc., maybe exploring how to leverage more of the Java engine would make more sense than trying to continue on the CF rendering engine … I guess I just never thought to connect those dots before. Interesting. Guess my knee-jerk reaction would have been to build something like this with ActionScript + Flash though. Cool man.

  9. Mazes in 3D at BarneyBlog

    [...] « 3D Rendering with CFML Circling a Cube in 3D [...]