News Mar 20: R.U.B.E v1.7 released. Instanciable objects!
Feb 21: Added RUBE sample loader for Cocos2d-X v3.4.
Feb 17: Funny Fists released in iOS App store and Google Play store. (YouTube video)
2014
May 25: R.U.B.E v1.6 released. Samplers!
May 12: "On-the-fly" resource updating for Cocos2d-x
Apr 22: New blog post: Inverted pendulum control
Apr 7: On-screen logging class for Cocos2d-x
Mar 22: Downhill Supreme 2 released for iOS and Android
Jan 2: YouTube video: Making soft-body wheels in RUBE
2013
Oct 6: Check out Supplyfront RTS, my 7dRTS entry continued.
Sep 26: R.U.B.E v1.5 released. Customizable item labels, snap-to-grid, export filtering, full-text help search.
Sep 18: Added RUBE sample loader for Cocos2d-X.
Sep 16: Updated RUBE sample loader for Cocos2d v2.
Aug 12: RUBE loader for Nape by Zeh Fernando
Aug 7: Added RUBE sample loader for SFML.
Jul 30: Try my MiniLD 7dRTS entry.
Jul 24: Added physics-driven particles tutorial.
Jul 20: New blog post: rendering solid ground (as in Downhill Supreme)
Jul 18: R.U.B.E v1.4 released. Command-line interface for batch jobs, hotkeys for scripts, better script management.
May 22: Downhill Supreme is out now! (iOS)
Apr 2: R.U.B.E v1.3 released. Collision bitplane editing, Cocos2d-iphone loader, usability improvements.
Mar 11: R.U.B.E v1.2 released. Now supports weld, friction, motor joints and automatic image reloading.
Mar 10: RUBE loader for libGDX by Tim Scott
Jan 28: New blog post: a functional combustion engine!
Jan 22: New blog post: wind tunnel
Jan 20: Added explosions tutorial.
Jan 16: Added buoyancy tutorial.
Jan 16: AndEngine sample project to load RUBE scene by Bart Hirst
Jan 14: R.U.B.E v1.1 released, now supports custom properties.
Jan 1: All basic tutorials are now available in Chinese at ohcoder.com Huge thankyou to @OhCoder!
2012
Dec 23: Discussion forums have been set up
Dec 4: R.U.B.E v1.0 is ready !
Dec 2: YouTube video: Box2D pendulum clock
Nov 26: New blog post: rocket platform thingy
Nov 25: Video of R.U.B.E scenes in Chipmunk.
Nov 23: A sample project to load R.U.B.E scenes into Chipmunk physics! Details here.
Nov 14: An XCode sample project to load R.U.B.E scenes on iOS is now available. Details here.
Nov 11: A Java version of b2dJson is now available, based on JBox2D.
Nov 6: A Javascript version of b2dJson based on box2dweb is now available. Demo here!
Nov 2: The full specification of the JSON format used by b2dJson can be found here: b2dJson file structure
Oct 28: YouTube video: 2-minute ragdoll in R.U.B.E Box2D editor
Sep 29: YouTube video: R.U.B.E Box2D editor usage example
Created: July 20 2013

Rendering solid ground


A few people have asked how the ground was rendered in Downhill Supreme. If you haven't seen the game, here is a video you can take a look at to see what we're talking about.


The ground is a 3d mesh, generated automatically from a single ground line. A very narrow field of view is used so that the mesh does not obscure the ground line which is the focus of the gameplay, yet still has some 3d depth to avoid having a perfectly flat appearance. After puzzling over various ways to make the ground, we eventually came up with this idea because it has quite a few advantages:
  • fully automatic, only a single line necessary
  • concavity is not a problem
  • large vertical ranges are not a problem
  • pre-baked lighting for fast rendering
  • custom color can be used for specific areas
  • easily divisible into chunks to reduce overdraw
  • looks good!
With Downhill Supreme now including 88 tracks, the first of these points is a very important one. Let's take a look at how the mesh is generated.

Starting with the original ground line (b2ChainShape) that the bike actually rides on, the normal at each vertex is extended downwards: Rendering solid ground The ends of adjacent normals are connected to from a second line underneath the original. In some places this gives a line that crosses over itself: Rendering solid ground The new line is checked for these self-intersections, and they are removed by ignoring any points between the intersection (the blue points in the image below), and replacing them with the intersection point itself. All points from the original line that were connected to ignored points, will now be connected to the new point. Rendering solid ground It can take a few iterations of this to clean the new line properly. Some other cleaning is done too, like making points that are very close together into a single point. More new lines are then added so that after a few iterations you get something like this. Rendering solid ground In Downhill Supreme, the distance to the new line is increased as each successive line is added (d = n^3) to make it look like the ground curves toward being flat at the top: Rendering solid ground The last line is then moved downward by a few hundred units to make sure it will always be offscreen even when the camera zooms out a lot. Rendering solid ground So far this is all entirely 2d. To make a 3d mesh, the points in each line are given gradually increasing z values, related to their distance from the original ground line. This is also based on n^3, so that if you look at the mesh from the side, you would see something like this: Rendering solid ground Now that the mesh is 3d, the color for each polygon is calculated by taking the dot product of the polygon normal with a constant directional 'sun' vector: Rendering solid ground The brightness is also scaled down linearly giving the last two lines in the mesh a fixed brightness of 0.2 so that no features are distinguishable, and the ground fades into a block of solid color: Rendering solid ground The mesh is given some random jitter by moving each point a little (except for the original line of course) to take away some of the sterile look, especially in smooth sections of the track as on the left here: Rendering solid ground Color is calculated based on colored points placed around the scene. Each polygon takes its color from the closest of the colored points to itself. Another color setting for the topmost layer is applied across the whole track, to give the effect of a dirt track on grass, etc: Rendering solid ground It turned out that with the number of tracks made, placing individual color points around all of them was too time-consuming. But here is an illustration of how they can be used to splat color onto the mesh. The purple point is just to illustrate how vertex color is taken from the closest color point. There are dozens of other color points under the ground which are not visible here but work in exactly the same way: Rendering solid ground After lighting calculation, the final color is randomized a little more, because otherwise polygons facing away from the sun are all the same color giving a very bland look and loss of texture: Rendering solid ground Once all this is ready, the vertex and color data is written to file as so that it can be quickly loaded into arrays ready for glColorPointer and glVertexPointer. Because the final colors have already been calculated, the game can render this mesh with no lighting or texturing for a better framerate. The mesh is also broken up horizontally into sections of a size such that only 2-3 sections are onscreen at any given time, and only those chunks of the mesh are rendered. This means that there are rarely more than about 2000 vertices being drawn, and helps to keep the framerate at 60fps even on 3G devices.