Category Archives: C#

Clarifying Balders feature set

Hopefully I’m not forgetting anything (probably am) – but below is a clarification of what features Balder has.

Coordinate system

Balder uses a left-handed coordinate system – currently there is no way to change this, but there are plans for opening up for any coordinate system.

Nodes

  • Interaction – one can enable interaction on any nodes and they can be interactively manipulated during runtime
  • Position coordinates
  • Rotation coordinates, in angles for each axis
  • Scale coordinates
  • Hierarchical rendering of nodes

Scene

  • A Scene contains objects, any Balder object implementing the interface INode; Lights, geometries, sprites

Viewport

  • Defines a clipping area on the screen, coordinate relative to its container

View

  • Camera
    • Position
    • Target
    • Field Of View

Sprites

  • Flat image based objects that exist in 3D space – they are rendered along with other 3D content and positioned and scaled correct according to their 3D space position.

Geometries

  • Box – simple box with dimensions
  • Cylinder – top and bottom dimensions can be specified independently
  • Ring – inner and outer circle dimensions can be specified independently
  • ChamferBox – simple box with a chamfer segment
  • HeightMap – a plane that consist of a set of vertices (points) that can be manipulated by its height
  • ArbitraryHeightMap – a derivative of HeightMap, but its plane is arbitrary
  • Mesh – a complex mesh which can be loaded from a file

Other objects

  • Container – not renderable itself, but can contain any Node in it – hierarchically

Assets

All data loaded from disk or elsewhere is known as Assets. There are Asset loaders for file types, you can even create your own Asset loaders quite easily. For Silverlight, there exist today a limitation which only allows loading of assets found in the XAP file – meaning that any asset added to the project must be a Resource in the XAP file. This is being worked on and will in a future release be more flexible.

  • ASE file – supports 90% of the Autodesk Ascii Scene Export format for 3D objects
  • Experimental support for Demoniak3D format
  • JPEG, PNG for Images

Assets are cached in a content manager, which means that if you load the same asset twice, it will clone the first one.

Lighting

  • OmniLight – non directional light, emits light in all directions
  • DirectionalLight – emits light in a specific direction, without any starting point or ending point
  • ViewLight – view dependent light that will always emit from the view and into the Scene

Rendering

  • Z buffered rendering
  • Flat shaded – single color faces
  • Gouraud shaded – color can be specific on each corner of a triangle
  • TextureMapping – perspective corrected, gouraud shaded.
  • Lines
  • Passive rendering mode – renders only when there are changes
  • Bilinear filtering
  • Face-culling – do not render faces/triangles facing away, can be controlled via Materials
  • Frustum-culling – objects not inside view will not be rendered – increases performance a lot

Materials

  • Diffuse color
  • Diffuse map
  • Ambient color
  • Specular color
  • Reflection map
  • Opacity for the different maps can be specified

Imaging

  • Supports PNG and JPEG
  • For textures, you must use images with dimensions being power of 2 (2,4,8,16,32,64,128,256,512,1024 and so on)

Input

  • For Silverlight; mouse events are supported (MouseEnter, MouseLeave, MouseMove, MouseLeftButtonDown, MouseLeftButtonUp)
  • Manipulation events for all Nodes to make it easier to interact with objects

Debug visualization

  • Bounding information
  • Show vertices

Statistics

  • Rendering timing
  • Amount of faces being rendered
  • Amount of objects being rendered

Execution

  • Actor system with statemachine for actors in the scene
  • Game – base class for any game

Silverlight / Windows Phone 7 specifics

  • Full XAML support – you can declaratively do everything that Balder can do in XAML
  • Specific CoordinateAnimation that can be used in storyboards for animating properties on Nodes
  • NodesControl / NodesStack – databindable controls that be bound to any source with NodeTemplate to specify its representation on screen. Similar to ItemsControl found in Silverlight.


Balder – vertex colors

I’ve been working lately on a demo that is for gaming a lot more realistic than the spinning teapot or box that one sees in the sample browser for Balder. A friend of mine Peter Rosenlund, an excellent graphics artist, gave me a 3D model of a city that I can use for that (thanks a lot!!).

In the 3D model, he had applied static lighting manually in 3DSMAX by painting the Vertex colors – a feature I had not implemented in Balder. After a few hours yesterday and this morning, I got it all up and running and I must say it looks kinda nice.

Balder, rendering city without vertex colors applied:

Balder_Without_VertexColors

Balder, rendering same city with the vertex colors applied:

Balder_With_VertexColors

 

Balder – Upcoming release

Its been some 4 months since the last official binary drop of Balder and its just about time to get a new version out. The reason for the "hold up" is that I've been quite busy with working 2 jobs; my daytime job and Balder related freelance work at night. Combining that with having a family of 2 kids and a wife, there simply hasn't been any time left get binaries out there. 

But, as part of the work that I've been doing freelance, Balder has gotten a lot of improvements. Among these are the following : 

– Further optimizations in the rendering pipeline

– Rewritten NodesControl, speed up and more capable

– General cleanups

– More Xml comments for documentation purposes

– Retrofitted some unittests

– Mouse events working properly

– Tooltip for Nodes

– Arbitrary Heightmap – corners of heightmap can be placed anywhere

– New AseLoader with more support than before (Smoothings groups, more objects, more material details, colors++)

– Rewritten AssetLoader system

– Fixed bugs with primitives

– More samples in SampleBrowser

– Visual Studio 2010 solution + project files

– Optimized lighting

– Added ViewLight – lighting relative to view, basically directional lighting

– Passive Rendering, making the rendering halt unless properties are changed on any object in the scene

– Content caching for faster startups

– A lot of code cleanups for decoupling the platform even more

– Material detection for mouse events 

 

And a whole bunch of other improvements.

The only thing left before a release can be done is to tie together some lose ends and fix a couple of bugs – then its ready for deployment. I'll be sure to post about all the new features and how they can be used in a post when the release is ready.

The next iteration will focus more on increasing code quality, more cleanups, get more documentation up and running, continuous integration server up and running and things that will improve further development on the project. 

First go with the EQATEC Silverlight Profiler

Its been a little more than 24 hours since I started playing with the EQATEC profiler and have identified bottlenecks in Balder that is close to impossible to discover without a profiler. One of things I really liked about the EQATEC profiler was its really easy to use user interface, its super-intuitive and I got up and running in seconds and could drill down straight to the bottlenecks just as fast. What impresses me with the profiler is the speed of it, I've worked with quite a few profilers in the past for the desktop – and they have always surprised me in a negative way with the amount of memory they use and not to mention the enourmous datafiles they generate. EQATECs just feels right, kudos to Richard Flamsholt and his team in Denmark for this product. You can download a free/personal license from here.

I thought I just give a quick guide into how its used.

The profiler is not integrated in Visual Studio and does not need to instrument your assemblies during compiletime, it works on the binary output of your compiled output. After starting the profiler, you need to point the profiler to your output directory in which the binaries for your application resides, typically the bindebug directory in your Visual Studio project folder. Click the browse button as shown below:

The first time you run it and if you have 3rd party assemblies that are signed you'll be asked to include or exclude these – the default recommendation is to exclude these. There is a resigning option included as well, but I didn't need this so I just skipped them. After it completes gathering your assemblies and recognizes the Silverlight app by finding the testpage and everything, you can go ahead and click the Build button in the lower right corner. It will instrument your binaries and add hooks for all your methods.

Then you just simply click the "Run App" button and your application will start and performance samples will be collected. You now need to play around in your application for the profiler to get enough data to play with.

After stopping your application, you'll be presented with the sample output with details of when it was profiled, its size and total time it ran.

Double click the session you want to view (if you have more than one) and you can start to drill into method calls with the summary sitting on top and a more visualized version of the method with drilldown capabilities at the bottom.

 

 Simple drill down and you'll see the amount of time spent in every method you drill down into:

 

And further: 

 

 

This is by far, in my oppinion, the best tool that has been released since Silverlight was released. It completes the developer experience and finally we can really show the full potential of Silverlight and the power the CLR actually gives us.

Thanks again to EQATEC for the donation to Balder – we will certainly make use of the license and optimize as close as we can to clock-cycles. 🙂 

 

 

Balder 0.8.8.6 is out

UPDATE 8th of July 2010 : 0.8.8.7 is out – read more here.

Finally after a couple of months of hard work and polishing the code, API and performance, version 0.8.8.6 ofBalderis out. A SampleBrowser can be found here for viewing most of the features ofBalder.
The features that has changed or is new are as follows:

* Introduced Silverlight in Core, but still maintaining platform independence
– Using core objects directly in Xaml can now be done

* Removed all controls in Balder.Core.Silverlight.Controls – not needed anymore

* Introduced View namespace with IView interface and Camera implementing it

* Viewport has View property insted of Camera

* Moved rendering from a multithread environment to run synchronously on the CompositionTarget. It gives better performance, due to synchronization issues between all threads. Will be revisited in the future.

* New drawing routines, optimized

* Heightmap primitive

* Box primitive

* Rotation, Scale on nodes

* Cylinder primitive

* DebugLevel is known as DebugInfo

* Material system in place

* Support for ReflectionMapping on materials

* Double sided materials

* Sprite rendering with alpha channel

* NodesControl – datadriven nodes control with templating – In Balder.Silverlight.Controls

* NodesStack – datadriven stacking of nodes with templating – in Balder.Silverlight.Controls


Balder 0.8.8.6 is out

UPDATE 8th of July 2010 : 0.8.8.7 is out – read more here.

Finally after a couple of months of hard work and polishing the code, API and performance, version 0.8.8.6 ofBalderis out. A SampleBrowser can be found here for viewing most of the features ofBalder.
The features that has changed or is new are as follows:

* Introduced Silverlight in Core, but still maintaining platform independence
– Using core objects directly in Xaml can now be done

* Removed all controls in Balder.Core.Silverlight.Controls – not needed anymore

* Introduced View namespace with IView interface and Camera implementing it

* Viewport has View property insted of Camera

* Moved rendering from a multithread environment to run synchronously on the CompositionTarget. It gives better performance, due to synchronization issues between all threads. Will be revisited in the future.

* New drawing routines, optimized

* Heightmap primitive

* Box primitive

* Rotation, Scale on nodes

* Cylinder primitive

* DebugLevel is known as DebugInfo

* Material system in place

* Support for ReflectionMapping on materials

* Double sided materials

* Sprite rendering with alpha channel

* NodesControl – datadriven nodes control with templating – In Balder.Silverlight.Controls

* NodesStack – datadriven stacking of nodes with templating – in Balder.Silverlight.Controls


Upcoming Balder release – 0.8.8.6

Its been crazy weeks since I decided to pull 0.8.8.5, but it was for the better. The result is that the rendering speed and quality has gone up quite dramatically. The next version of Balder will be 0.8.8.6 and will contain at least the following: 

– Optimized framebuffer management

– Optimized drawing/rendering

– Optimized lighting

– Proper polygon clipping against the viewport 

– Completely refactored way of handling objects, no duplication in the type hierarchy for Balder, like in 0.8.8.0.

– New controls : NodesControl, NodesStack – similar as Canvas and StackPanel works with 2D elements in Silverlight

– New geometry types; Box, Cylinder, Plane

– Transparency for objects / materials

– Introducing the concept of View, you can now create custom cameras

– DebugLevel is no longer flag-based, but a self contained object with properties for all Debug options

– Rendering is now synchronously – gives better framerate in most scenarios, but hogs up rendering event. Ongoing process.

 

Its been crazy since december with a lot of work being put into Balder and more to come. I don't have a date yet for when I'll have the release, but I'll try to push it as soon as I'm content with the result. 

 

Upcoming Balder release – 0.8.8.6

Its been crazy weeks since I decided to pull 0.8.8.5, but it was for the better. The result is that the rendering speed and quality has gone up quite dramatically. The next version of Balder will be 0.8.8.6 and will contain at least the following: 

– Optimized framebuffer management

– Optimized drawing/rendering

– Optimized lighting

– Proper polygon clipping against the viewport 

– Completely refactored way of handling objects, no duplication in the type hierarchy for Balder, like in 0.8.8.0.

– New controls : NodesControl, NodesStack – similar as Canvas and StackPanel works with 2D elements in Silverlight

– New geometry types; Box, Cylinder, Plane

– Transparency for objects / materials

– Introducing the concept of View, you can now create custom cameras

– DebugLevel is no longer flag-based, but a self contained object with properties for all Debug options

– Rendering is now synchronously – gives better framerate in most scenarios, but hogs up rendering event. Ongoing process.

 

Its been crazy since december with a lot of work being put into Balder and more to come. I don't have a date yet for when I'll have the release, but I'll try to push it as soon as I'm content with the result. 

 

Dispatcher Safe INotifyPropertyChanged

Update, 19th of November 2011:

Eduardo Elias Mardini Bitar did an article for the CodeProject with some updates and improvements.

 

One of the things I really love in Silverlight is the promotion of non-locking UIs through heavy use of asynchronous operations for things like webservice calls. The main problem though with this is that it is running on a different thread than the UI thread and you can't modify anything on the UI without running on the same thread. This even goes for databinding, so if you have properties on an object databound in the UI and you set the value on any of these properties, you still need to be on the UI thread in order for this to work. This is also true for WPF applications.

The way you could do this is to get an instance of the Dispatcher and use the BeginInvoke() method on it. In Silverlight there is only one Dispatcher and it can be retrieved from the Deployment object in System.Windows; Deployment.Current.Dispatcher. In WPF there can be several Dispatchers, so it gets a bit more complicated, you'd have to do Dispatcher.FromThread() and use the current thread during the add method of your PropertyChanged and store it alongside with the instance of the delegate to know which Dispatcher to invoke a change on.

 When I first wrote my automagically implemented INotifyPropertyChanged post, it didn't have this support. I knew I needed it to support it, but I didn't want to have a dependency directly to the Dispatcher found in the Deployment object, as my unit tests would have a hard time coping with that dependency. I needed to abstract it away so I could have a cleaner way of doing this and be able to test it without too much hassle. By introducing an interface representing the Dispatcher, I was halfway there, but had no way of injecting this into the proxy types being created. The problem is that you can't define a constant on the type that holds a reference to a ref object, it only supports value types. I really struggled a full day with this, I was trying to not have any dependencies from the proxies in order to get the Dispatcher, and I didn't want to tie it up to just be compatible with IoC containers and specifically NInject that I'm using for the most part. The result is that I had to implement a DispatcherManager and have a private field on the proxy type holding a reference to an IDispatcher and let the manager control which implementation it got. This worked out nicely, even though it now have a dependency to the DispatcherManager directly. 

This has all been implemented into the Balder project, as I need it for my SampleBrowser I'm working on, the code is located inside the Notification namespace and can be found here

What does it do?
Lets say you have your object like below, the virtuals are in there for the weaver to be able to implement these properties in its proxy (as eplained in my previous post). 

[code:c#]
public class Employee
{
    public virtual string FirstName { get; set; }
    public virtual string LastName { get; set; } 
}
[/code]

The weaver will then go and inject its magic, the end result is pretty much like this:
[code:c#]
public class EmployeeProxy : Employee, INotifyPropertyChanged
{
    private IDispatcher _dispatcher = DispatcherManager.Current;

    public event PropertyChangedEventHandler PropertyChanged;

    public override string FirstName
    {
        get { return base.FirstName; }
        set
        {
            base.FirstName = value;
            OnPropertyChanged("FirstName");
        }
    }

    public override string LastName
    {
        get { return base.LastName; }
        set
        {
            base.LastName = value;
            OnPropertyChanged("LastName");
        }
    }

    private void OnPropertyChanged(string propertyName)
    {
        if( null != PropertyChanged )
        {
            if( _dispatcher.CheckAccess() )
            {
                PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
            }
            else
            {
                _dispatcher.BeginInvoke(PropertyChanged,this, new PropertyChangedEventArgs(propertyName));
            }
        }
    }

}
[/code] 

Dispatcher Safe INotifyPropertyChanged

Update, 19th of November 2011:

Eduardo Elias Mardini Bitar did an article for the CodeProject with some updates and improvements.

 

One of the things I really love in Silverlight is the promotion of non-locking UIs through heavy use of asynchronous operations for things like webservice calls. The main problem though with this is that it is running on a different thread than the UI thread and you can't modify anything on the UI without running on the same thread. This even goes for databinding, so if you have properties on an object databound in the UI and you set the value on any of these properties, you still need to be on the UI thread in order for this to work. This is also true for WPF applications.

The way you could do this is to get an instance of the Dispatcher and use the BeginInvoke() method on it. In Silverlight there is only one Dispatcher and it can be retrieved from the Deployment object in System.Windows; Deployment.Current.Dispatcher. In WPF there can be several Dispatchers, so it gets a bit more complicated, you'd have to do Dispatcher.FromThread() and use the current thread during the add method of your PropertyChanged and store it alongside with the instance of the delegate to know which Dispatcher to invoke a change on.

 When I first wrote my automagically implemented INotifyPropertyChanged post, it didn't have this support. I knew I needed it to support it, but I didn't want to have a dependency directly to the Dispatcher found in the Deployment object, as my unit tests would have a hard time coping with that dependency. I needed to abstract it away so I could have a cleaner way of doing this and be able to test it without too much hassle. By introducing an interface representing the Dispatcher, I was halfway there, but had no way of injecting this into the proxy types being created. The problem is that you can't define a constant on the type that holds a reference to a ref object, it only supports value types. I really struggled a full day with this, I was trying to not have any dependencies from the proxies in order to get the Dispatcher, and I didn't want to tie it up to just be compatible with IoC containers and specifically NInject that I'm using for the most part. The result is that I had to implement a DispatcherManager and have a private field on the proxy type holding a reference to an IDispatcher and let the manager control which implementation it got. This worked out nicely, even though it now have a dependency to the DispatcherManager directly. 

This has all been implemented into the Balder project, as I need it for my SampleBrowser I'm working on, the code is located inside the Notification namespace and can be found here

What does it do?
Lets say you have your object like below, the virtuals are in there for the weaver to be able to implement these properties in its proxy (as eplained in my previous post). 

[code:c#]
public class Employee
{
    public virtual string FirstName { get; set; }
    public virtual string LastName { get; set; } 
}
[/code]

The weaver will then go and inject its magic, the end result is pretty much like this:
[code:c#]
public class EmployeeProxy : Employee, INotifyPropertyChanged
{
    private IDispatcher _dispatcher = DispatcherManager.Current;

    public event PropertyChangedEventHandler PropertyChanged;

    public override string FirstName
    {
        get { return base.FirstName; }
        set
        {
            base.FirstName = value;
            OnPropertyChanged("FirstName");
        }
    }

    public override string LastName
    {
        get { return base.LastName; }
        set
        {
            base.LastName = value;
            OnPropertyChanged("LastName");
        }
    }

    private void OnPropertyChanged(string propertyName)
    {
        if( null != PropertyChanged )
        {
            if( _dispatcher.CheckAccess() )
            {
                PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
            }
            else
            {
                _dispatcher.BeginInvoke(PropertyChanged,this, new PropertyChangedEventArgs(propertyName));
            }
        }
    }

}
[/code]