[ANN] librend 0.0.1

Here's something I've been hacking on for the past two months, an OpenGL
scenegraph engine written mostly in Ruby with some critical sections
inlined in C. It's been a educational experience :slight_smile:

Librend is a simple scenegraph engine on top of OpenGL, SDL, Imlib2,
GLEW and Cairo that aims to make it quick and easy to write apps that
mix 2D, 3D and vector graphics.

I'm dubious about its suitability for public consumption at this stage
but I'll release it anyhow :I

Comments and questions welcome!

Homepage: http://librend.rubyforge.org/
Screenshots: http://librend.rubyforge.org/screenshots/
API docs: http://librend.rubyforge.org/rdoc/
Downloads: http://rubyforge.org/frs/?group_id=716

From the Rend module docs:

Librend implements a scenegraph 3D engine. The graph is a tree, and is
read from the root upwards.

You create Rend::Models and attach children to them. The models are then
drawn from root upwards, with the children using the properties of their
parents as the default.

Transforms cascade, so an object 4 levels down the tree has its base
position and rotation determined by applying all the positions and
rotations of its parents.

The scene root is given to the renderer, which draws the scenegraph to
the screen. There are no (well, shouldn每t be) rendering API specific
parts in the scene graph, so it每s quite API-independent. (Note: This is
not entirely true, there are some places which use API-specific
functions, e.g. the classes Sound and Shader and the current
unabstracted event model.)

Here每s an irb session showcasing setting up a scene and editing it on
the fly.

   require 'rend'

   # First, create the scene and some models.
   scene = Rend::Model.new
   ball = Rend::Sphere.new
   cube = Rend::Cube.new

   # Add the ball and the cube to the scene.
   scene.attach ball, cube

   # Set up the renderer and start running.
   renderer = Rend::Renderer.new
   renderer.scene = scene

   # Let's move the ball up...
   ball.position = [0, 2, 0]

   # ...and tweak the camera a bit.
   renderer.camera.fov = 60
   renderer.camera.looking_at[1] = 1
   renderer.camera.position[2] += 2

   # Wouldn't it be nice if the cube rotated?
   # Let's add a time handler to do just that.
   cube.add_time_handler{|o,t| o.rotation = [(t*100)%360, 1, 0, 1]}

   # Some light would be nice aswell.
   scene.lights = [Rend::Light.new(:position => [2, 5, 3])]

   # The camera should orbit our scene, right?
   renderer.camera.add_time_handler{|o,t|
     o.position = [4.0*Math.sin(t/2), 2.0, 4.0*Math.cos(t/2)]
   }

   # The cube rotation makes the orbiting look all weird,
   # let's take it out.
   cube.time_handlers.clear

   # The ball looks a bit crude, let's add some detail.
   ball.geometry.radial_detail = 150
   ball.geometry.axial_detail = 150

   # And make it shiny red!
   ball.material = Rend::Material.new
   ball.material.diffuse = [1, 0, 0, 1] # red diffuse
   ball.material.specular = [1, 1, 1, 1] # white specular
   ball.material.shininess = 150

   renderer.thread.kill # Oops, there goes our eventloop
   renderer.run # but we can restart it
   renderer.thread.join # and wait until someone exits the program

Wow, haven't tried it but looks really great!

Ghislain

Wow, very impressive!

Cheers,

Erik.

Ilmari Heikkinen wrote:

Here's something I've been hacking on for the past two months, an OpenGL
scenegraph engine written mostly in Ruby with some critical sections
inlined in C. It's been a educational experience :slight_smile:

Very nice, keep it up! Do you think this will ever be a replacement for the Tk 2D canvas? I'm thinking of things like layers, groups, event bindings, etc. Actually, I guess event bindings wouldn't make sense outside of a GUI context. Maybe librend could be integrated into Fox?

This is a really interesting library, I'm currently using
OpenSceneGraph (http://www.openscenegraph.org), a C++ scenegraph
library, at my work. However, this library is very interesting.

Can you comment a little more on the vector graphics? Are you trying
to render vector graphics in OpenGL? Are graph traversals one of the
areas you've inlined? Or are you doing that in Ruby? ( I guess I should
download it and look for myself :slight_smile:

- alan

Ilmari Heikkinen wrote:

Here's something I've been hacking on for the past two months, an OpenGL
scenegraph engine written mostly in Ruby with some critical sections
inlined in C. It's been a educational experience :slight_smile:

Very nice, keep it up!

Thanks, will do!

Do you think this will ever be a replacement for the Tk 2D canvas? I'm thinking of things like layers, groups, event bindings, etc. Actually, I guess event bindings wouldn't make sense outside of a GUI context. Maybe librend could be integrated into Fox?

I'm not familiar with the Tk canvas, but after reading through the man page it seems that most of the drawing functionality can be implemented with the vector engine. Layers and groups are quite doable already in some form, though not quite at Photoshop level, heh.
Do you have some specific thing in mind regarding the layers, what should they do?

Event bindings are there, but use SDL events at the moment. I'll abstract them to a generic event model today, then the window system backend shouldn't matter. There are no mouse cursor hit detection helpers yet, so one now either needs to keep tab of where everything is and react based on that (royal pain, especially with rotating things) or write a general picking system for the renderer. I'll try to get a picking system going soon.

Fox integration should be doable by writing a backend for the renderer. It needs to initialize GL, tell the renderer the window dimensions and pass input events to it.

Cheers,
Ilmari

路路路

On 2.6.2005, at 21:03, Joel VanderWerf wrote:

pe, 2005-06-03 kello 01:30, Alan Chen kirjoitti:

This is a really interesting library, I'm currently using
OpenSceneGraph (http://www.openscenegraph.org), a C++ scenegraph
library, at my work. However, this library is very interesting.

Thanks for the interest and questions :slight_smile:

Can you comment a little more on the vector graphics? Are you trying
to render vector graphics in OpenGL?

I'm using rcairo to draw vector graphics to textures. But it would be
nice to have an OpenGL vector renderer aswell. Then the vector elements
could work better with the rest of the scene and wouldn't eat so much
memory.

Are graph traversals one of the areas you've inlined?

Yes. The inlined methods basically were the top 5 in profiler chart.

Ilmari Heikkinen wrote:

...

Do you think this will ever be a replacement for the Tk 2D canvas? I'm thinking of things like layers, groups, event bindings, etc. Actually, I guess event bindings wouldn't make sense outside of a GUI context. Maybe librend could be integrated into Fox?

I'm not familiar with the Tk canvas, but after reading through the man page it seems that most of the drawing functionality can be implemented with the vector engine. Layers and groups are quite doable already in some form, though not quite at Photoshop level, heh.
Do you have some specific thing in mind regarding the layers, what should they do?

For example: a "car" is composed of several 2D shapes plus some text that floats alongside it. The shapes are all at the same level (above the roadway, let say), but the text is at a higher level. So if two cars pass near each other, the text is not obscured. I've sometimes emulated that in OpenGL by using very small z-axis values, but it seems like a hack to use 3D drawing at all in this case.

Event bindings are there, but use SDL events at the moment. I'll abstract them to a generic event model today, then the window system backend shouldn't matter. There are no mouse cursor hit detection helpers yet, so one now either needs to keep tab of where everything is and react based on that (royal pain, especially with rotating things) or write a general picking system for the renderer. I'll try to get a picking system going soon.

Fox integration should be doable by writing a backend for the renderer. It needs to initialize GL, tell the renderer the window dimensions and pass input events to it.

Great! Keep us posted.

路路路

On 2.6.2005, at 21:03, Joel VanderWerf wrote:

pe, 2005-06-03 kello 01:33, Joel VanderWerf kirjoitti:

Ilmari Heikkinen wrote:
>
...
>> Do you think this will ever be a replacement for the Tk 2D canvas? I'm
>> thinking of things like layers, groups, event bindings, etc.

> Do you have some specific thing in mind regarding the layers, what
> should they do?

For example: a "car" is composed of several 2D shapes plus some text
that floats alongside it. The shapes are all at the same level (above
the roadway, let say), but the text is at a higher level. So if two cars
pass near each other, the text is not obscured. I've sometimes emulated
that in OpenGL by using very small z-axis values, but it seems like a
hack to use 3D drawing at all in this case.

Yes, actually there are a couple of ways to achieve this.

In the vector scenes the elements are ordered by z-index to build a
drawing list. But there are is no layer abstraction. Hmm, maybe it could
be done by normalizing the z-indices inside a layer to [0,1) and then
adding the layer index to that. Or, better yet, draw each layer on its
own surface and blend them together in the end.

There are also renderer "layers"; the renderer draws Views, which have a
viewlist. The viewlist is composed of [camera, scene, effects]-tuples,
which the renderer draws in order, clearing the depth buffer between
them. So it's possible to draw a perspective-projected scene first,
followed by e.g. name markers, and then an ortho-projected HUD on top.

路路路

> On 2.6.2005, at 21:03, Joel VanderWerf wrote:

If the Text labels are positioned at the centroid of the object they are labeling, and the cameras for each views are matched to the same world space, this is an effective way of visually layering the content. However, the downside of this technique is that EVERY label is always visible, even if the part if fully occluded by other geometry.

Another (math-intensive) solution is to offset the pivot point of the text so that it rotates about the center of the object being labelled, but offset towards the camera the distance necessary for the billboarded bounding box of the text to fully clear the geometry of the object being labeled. As other objects move in front of the part/label, the label will be occluded along with the rest of the part.

Deriving the billboarding code, pivot offset/rotation, and box-on-geometry collision detection is left as an exercise to the reader :wink:

路路路

On Jun 3, 2005, at 12:26 AM, Ilmari Heikkinen wrote:

There are also renderer "layers"; the renderer draws Views, which have a
viewlist. The viewlist is composed of [camera, scene, effects]-tuples,
which the renderer draws in order, clearing the depth buffer between
them. So it's possible to draw a perspective-projected scene first,
followed by e.g. name markers, and then an ortho-projected HUD on top.

--
"Contrary to what most people say, the most dangerous animal in the
world is not the lion or the tiger or even the elephant. It's a shark
riding on an elephant's back, just trampling and eating everything they
see." -- Jack Handey