Planning the Spontaneous

It's more than just a blueprint.

Archive for April, 2010

MultiOpenGlControl Demo

Posted by Robert Chow on 16/04/2010

I’ve managed to grab some video capture software and also produce a small demo of using multiple SimpleOpenGlControls.  Each screen has it’s own camera, focusing on to the same scene.  Using lighting and picking, clicking a face of the cube will change the scene, and thus be reflected in all of the cameras.

I did have a little trouble with the picking at first – when I picked, I forgot to change the current camera, so it would register the mouse click on one screen whilst using the camera of another.  With that fixed, it was nice to be able to play around with Renderer again.

True, the videos not suppose to be a hit, but at least it’s showing what I want it to.

Advertisements

Posted in Computing, Placement | Tagged: , , , , , , , , , | Leave a Comment »

MultiOpenGlControl

Posted by Robert Chow on 14/04/2010

One thing I’ve only just come to tackle is the prospect of having more than one rendering context visible at any time.

Make Current

Using the Tao SimpleOpenGlControl, it’s a relatively simple feat.

MultiOpenGlControl.  Displaying two SimpleOpenGlControls in immediate mode is relatively easy.


The SimpleOpenGlControl class allows you to make the control as the current rendering context. Any OpenGl calls made after this will be applied to the most recently made current rendering context.

public void Init()
{
SimpleOpenGlControlA.InitializeContexts();
SimpleOpenGlControlB.InitializeContexts();
}

public void SimpleOpenGlControlAPaint(object sender, PaintEventArgs e)
{
SimpleOpenGlControlA.MakeCurrent(); // all code following will now apply to control A

Gl.glClearColor(1, 1, 0, 0);
Gl.glClear(Gl.GL_COLOR_BUFFER_BIT);

Gl.glMatrixMode(Gl.GL_PROJECTION);
Gl.glLoadIdentity();
Gl.glOrtho(-1, 1, –1, 1, 1, –1);

Gl.glMatrixMode(Gl.GL_MODELVIEW);
Gl.glLoadIdentity();

Gl.glColor3d(1, 0, 0);
Gl.glBegin(Gl.GL_POLYGON);
Gl.glVertex2d(-0.5, –0.5);
Gl.glVertex2d(0.5, –0.5);
Gl.glVertex2d(0, 0.5);
Gl.glEnd();

SimpleOpenGlControlB.Invalidate(); // I invalidate B so it gets refreshed – if I only invalidate A, B will never get drawn
}

public void SimpleOpenGlControlBPaint(object sender, PaintEventArgs e)
{
SimpleOpenGlControlB.MakeCurrent();  // all code following will now apply to control B

Gl.glClearColor(0, 1, 1, 0);
Gl.glClear(Gl.GL_COLOR_BUFFER_BIT);

Gl.glMatrixMode(Gl.GL_PROJECTION);
Gl.glLoadIdentity();
Gl.glOrtho(-1, 1, 1, –1, 1, –1); // NOTE: I have changed the projection to show the images differently

Gl.glMatrixMode(Gl.GL_MODELVIEW);
Gl.glLoadIdentity();

Gl.glColor3d(1, 0, 0);
Gl.glBegin(Gl.GL_POLYGON);
Gl.glVertex2d(-0.5, –0.5);
Gl.glVertex2d(0.5, –0.5);
Gl.glVertex2d(0, 0.5);
Gl.glEnd();

SimpleOpenGlControlA.Invalidate(); // I invalidate A so it gets refreshed – if I only invalidate B, A will never get drawn
}

Multiple Vertex Buffer Objects

I did run into a little trouble though. I found that when I was rendering in immediate mode, this worked fine.  However, when I came about to using vertex buffer objects and rendering in retained mode, I found the results were different.

MultiVertexBufferObjects.  Only one of the controls renders the image, despite making the exact same calls in each of the control’s paint methods.  You can tell the paint method of control A is called because the clear color is registered.


Only one of the rendering contexts shows an image, and the other did not, despite the obvious call to clear the color buffer.

int[] buffers = new int[3];
float[] vertices = new float[] { –0.5f, –0.5f, 0.5f, –0.5f, 0, 0.5f };
float[] colours = new float[] { 1, 0, 0, 1, 0, 0, 1, 0, 0 };
uint[] indices = new uint[] { 0, 1, 2 };

public void Init()
{
SimpleOpenGlControlA.InitializeContexts();
SimpleOpenGlControlB.InitializeContexts();

Gl.glGenBuffers(3, buffers);
Gl.glBindBuffer(Gl.GL_ARRAY_BUFFER, buffers[0]);
Gl.glBufferData(Gl.GL_ARRAY_BUFFER, (IntPtr)(vertices.Length * sizeof(float)), vertices, Gl.GL_STATIC_DRAW);
Gl.glBindBuffer(Gl.GL_ARRAY_BUFFER, buffers[1]);
Gl.glBufferData(Gl.GL_ARRAY_BUFFER, (IntPtr)(colours.Length * sizeof(float)), colours, Gl.GL_STATIC_DRAW);
Gl.glBindBuffer(Gl.GL_ELEMENT_ARRAY_BUFFER, buffers[2]);
Gl.glBufferData(Gl.GL_ELEMENT_ARRAY_BUFFER, (IntPtr)(indices.Length * sizeof(uint)), indices, Gl.GL_STATIC_DRAW);
}

public void SimpleOpenGlControlAPaint(object sender, PaintEventArgs e)
{
SimpleOpenGlControlA.MakeCurrent(); // all code following will now apply to control A

Gl.glClearColor(1, 1, 0, 0);
Gl.glClear(Gl.GL_COLOR_BUFFER_BIT);

Gl.glMatrixMode(Gl.GL_PROJECTION);
Gl.glLoadIdentity();
Gl.glOrtho(-1, 1, –1, 1, 1, –1);

Gl.glMatrixMode(Gl.GL_MODELVIEW);
Gl.glLoadIdentity();

Gl.glBindBuffer(Gl.GL_ARRAY_BUFFER, buffers[0]);
Gl.glVertexPointer(2, Gl.GL_FLOAT, 0, IntPtr.Zero);
Gl.glBindBuffer(Gl.GL_ARRAY_BUFFER, buffers[1]);
Gl.glColorPointer(3, Gl.GL_FLOAT, 0, IntPtr.Zero);

Gl.glEnableClientState(Gl.GL_VERTEX_ARRAY);
Gl.glEnableClientState(Gl.GL_COLOR_ARRAY);

Gl.glBindBuffer(Gl.GL_ELEMENT_ARRAY_BUFFER, buffers[2]);
Gl.glDrawElements(Gl.GL_POLYGON, indices.Length, Gl.GL_UNSIGNED_INT, IntPtr.Zero);

Gl.glDisableClientState(Gl.GL_VERTEX_ARRAY);
Gl.glDisableClientState(Gl.GL_COLOR_ARRAY);

SimpleOpenGlControlB.Invalidate(); // I invalidate B so it gets refreshed – if I only invalidate A, B will never get drawn
}

public void SimpleOpenGlControlBPaint(object sender, PaintEventArgs e)
{
SimpleOpenGlControlB.MakeCurrent(); // all code following will now apply to control B

Gl.glClearColor(0, 1, 1, 0);
Gl.glClear(Gl.GL_COLOR_BUFFER_BIT);

Gl.glMatrixMode(Gl.GL_PROJECTION);
Gl.glLoadIdentity();
Gl.glOrtho(-1, 1, –1, 1, 1, –1); // NOTE: I have changed the projection to show the images differently

// same code as above

SimpleOpenGlControlA.Invalidate(); // I invalidate A so it gets refreshed – if I only invalidate B, A will never get drawn
}

Multiple Vertex Buffer Objects

This is because if you are to generate buffers, the buffers only apply to the current rendering context – in this case, it is SimpleOpenGlControlB (it was the last one that was created).  If you are using buffers and want to render the same data in a different rendering context, you have to recreate the data buffers again under the different context.  It seems like a bit of a waste really – having to recreate the same thing twice just to view it in a different place.

public void Init()
{
SimpleOpenGlControlA.InitializeContexts();
SimpleOpenGlControlB.InitializeContexts();

SimpleOpenGlControlA.MakeCurrent();
// create bufferset

SimpleOpenGlControlB.MakeCurrent();
// repeat the same code to recreate the bufferset under a different rendering context
}

// Draw methods

Shared Vertex Buffer Objects

Fortunately, there is a small hack around. Wgl offers a method, wglShareLists, which allows for different rendering contexts to share, not only the same display lists, but also VBO, FBO and texture lists. To do this, you need to get the rendering context handles – unfortunately, you can only do this with a small hack around.

public void Init()
{
SimpleOpenGlControlA.InitializeContexts();
SimpleOpenGlControlB.InitializeContexts();

SimpleOpenGlControlA.MakeCurrent();
var aRC = Wgl.wglGetCurrent();
SimpleOpenGlControlB.MakeCurrent();
var bRC = Wgl.wglGetCurrent();

Wgl.wglShareLists(aRC, bRC);

// start creating vbos here – these will now be shared between the two contexts.
}

// Draw methods

Multiple Controls For Renderer

This now provides two solutions for Renderer – I can either have seperate lists for each control, or have them all share the same one.  There are advantages and disadvantages to both.

In terms of management, it would be a lot easier to have them share the same lists – there is an overhead in tracking what lists are part of which control.  It would also cause a problem when a user tries to draw a scene for a particular control, when the vertex buffer objects in the scene are assigned to a another.

It would also be advantageous to have shared lists when using heavy OpenGl operations, such as texture binding – it would have to bind a new texture each time a different control is refreshed.  Sharing a texture list would erase this problem.

In the short run, using seperate lists has its disadvantages; the memory use is rather inefficient because it has to create a new set of lists each time a control is created.  However, the memory story is a different matter when sharing lists becomes long term.   This is because once a control is destroyed, so too are its lists.  Sharing lists would mean the list will continue to accumulate more and more data until all the controls have been destroyed – that is entirely up to the user, and could take some time.

As a result, for the time being, I am going to go for the option of sharing lists – mainly because it does have its advantages in terms of not having to deal with the management side, and it also minimises the frequency of heavy OpenGl operations.  Not only this, but also because it would take some time to implement the management.  If  I do have time nearer the end of my placement, I may decide to come back and revisit it.

MultiOpenGlControl-3D.  Here is Renderer using 4 different SimpleOpenGlControls simultaneously.  I’ve tried to replicate a (very simple) 3D editing suite, whereby there are 3 orthogonal views, Front, Top and Side, and then the projection view.  It uses the same model throughout, but each control has differing camera positions.

Posted in Computing, Placement | Tagged: , , , , , , , , | Leave a Comment »

Bright Break

Posted by Robert Chow on 13/04/2010

Easter was interesting.  And tiring.

Not to mention the fact that I’ve never really celebrated it as far as receiving a chocolate egg, this years was definitely to say the least, different.

Although working for a majority of the Easter break, I spent the Sunday entertained with my cousins and family who decided to come visit Devon for their holidays.  They come every year apparently, and always do the same thing – an Easter egg hunt.  Can’t say I’ve ever done one before, and it was a lot more fun than expected.

But it’s the week after Easter which is why I am so tired.  My girlfriend decided to take what very little break she has from university and spend it down south, and so too did one of my course friends.

On the Wednesday, me and my girlfriend decided to borrow a couple of bicycles and cycle down the Tarka trail – something I’ve been meaning to do, but once again, like many other things, I’ve been putting off.  Instead of completing the Bideford-Barnstaple leg, we decided to go down the other way to Torrington, a place I’ve never been to.  It was rather interesting to see my girlfriend cycle for the first in 11 years – a few bumps and bruises were had!  And those seats weren’t the most comfortable either!  Yet, we finally made it in the end.

Tarka Trail House.


Tarka Trail River.


Puffing Billy.  We took this photo just to prove we had made it to Torrington (even though it wasn’t actually that far)!  We were recommended to try the food at the Puffing Billy, but unfortunately it was shut.


On Thursday we found ourselves at a leaving lunch for a couple of colleagues in Appledore.  We decided to stay around, but then realising there is absolutely nothing to do in Appledore, we decided to head towards Westward Ho! via Northam.  It only took about 50 minutes to walk and is quite nice, particularly if the weather is good.

Appledore To Instow.  This is the view from Appledore to Instow.  There’s not really much else.  They say that on the opposite of the river in Instow, the people are quite wealthy, and that those in Appledore are far less off.


Westward Ho!

My friend came round later that evening, and now with access to a car, we decided to go for a ‘nice’ walk near Saunton on Friday.  ‘Nice’ is a bit misleading.  The views were spectacular, and the route was quite enjoyable, but I think, it’s safe to say, we were a little unprepared. We took the coastal path to Woolacombe bay – that we were fine with.  We just didn’t quite realise how long it was, and unfortunately, we had to walk back to the car.   We resulted in going over the hills instead, on rather steep paths.  It sure was tiring, but it was a good (unplanned) 8.5 miles of exercise!  I’d recommend it to anyone who is willing enough for a struggle!

Coastal Rocks.

Croyde.

Cliffside.  It’s safe to say (or raher, unsafe) it’s quite steep!

Woolacombe Bay. Relief at last, until we realised we had to walk back.

Alien Saunton.  The view we had coming over the hills back to Saunton.  It had seemed as if we’d stepped into another world.

Coastal Walk.  This is the path that we took from Saunton to Woolacombe bay.  This image is taken from Google Maps.  You can find the map I’ve created at http://maps.google.co.uk/maps/ms?oe=utf-8&client=firefox-a&ie=UTF8&hl=en&msa=0&msid=107891036475706214108.000483e4e9b48ef32ebeb&ll=51.1317,-4.228878&spn=0.040181,0.090895&t=h&z=14

After the small break, it’s now back to work.  Me and my supervisor devised a (rather scary looking) timetable for me to try to stick to between now and the end of my placement.  It’s not too long now, only 3 more months!  A lot of work, and not a lot of time.  Hopefully, I’ll be pulling off a demo every single week – not necessarily anything particularly spectacular, but the by the end of the period, I should have a Grapher component done and polished.  I hope.

Posted in Placement | Tagged: , , , , , , , , , , , , | Leave a Comment »

Linq me

Posted by Robert Chow on 07/04/2010

It’s been more than a few months into my placement now, and my grasp of C# has really gone further than just ‘beginner’ now.

There is a lot of material about Linq on the Internet, and because I should have posted about it a lot earlier, I’m only just going to touch upon a small problem I had yesterday.

Linq

Linq stands for language-intergrated query and consists of a small number of extension methods allowing users to query an IEnumerable collection.   The idea is to allow similar to SQL type queries be made on a collection and are very useful.

Invalid Operation Exception : Collection was modified;

The problem I had was taking a collection, applying a filter and then using the filter to alter the original collection.  Here’s an example of the code.

var toDelete = aCollection.Take(20).Skip(10);
foreach(CollectionItem collectionItem in toDelete)
{
aCollection.Remove(collectionItem);
}

This takes a collection, and applies a filter to it using Linq. The Take(20) will take the first 20 items in aCollection.   Apply Skip(10) will then filter the result to take the remaining items after skipping the first 10 items.  In the foreach loop, I then attempt to delete the items I have filtered from the original collection.

It works fine for the first iteration, yet on the second it throws a nasty error, “Invalid Operation Exception : Collection was modified”.  I know I am modifying the original collection, yet strangely enough it is throwing the exception, expressing that I have modified the toDelete collection.  Nowhere in the loop do I touch the toDelete collection at all.

So it seems

Unfortunately, I do. The reference held by toDelete is the same reference as aCollection – modifying aCollection will also modify toDelete.   This is because when I assign toDelete, it takes the same reference as aCollection, and then includes the filters.  My first impression of using Take and Skip was that it would return a new collection, with just the filtered elements, alas, it is not to be.

Knowing this, I realise I need to take the filtered elements and recreate the filter in a new collection.  Fortunately, Linq can also help me do this.

toDelete = toDelete.ToList();

Seems a bit of a pain that the filter doesn’t actually give a new collection item. I hope that after reading this, you can also avoid similar problems as I did.

Posted in Computing, Placement | Tagged: , , , | Leave a Comment »

OOP

Posted by Robert Chow on 01/04/2010

OOP.  Object-orientated-programming.  Something that every programmer should be able to do nowadays writing a 3rd gen language.  With dynamic languages, I’m not entirely sure on how different it is, but I’m guessing the principles are the same.

But that’s not what I’m here to blog about.  I’ve managed to whip up a demo of the toolkit, OOP, or I’d like to call it, Object-Orientated-Paint.

Object-Orientated-Paint

So for those that use Microsoft Paint (and I still do), many will know how annoying it is to only have one canvas, and that every single dash or pixel “painted” on to the canvas is essentially there to stay unless another splash of paint writes over it.  It’s quite frustrating, especially when only a few minutes down the line do you realise that you forgot to draw something and therefore have to edit the whole picture.  Once you’ve edited that picture, you’ve also no way of going back either (the undo command only has a history of 3, something that has frustrated me rather a lot over the years).

So why better it by encapsulating each shape/splash of paint as an object?  It’s essentially what Microsoft Powerpoint uses.  True, you dont’ get the same precision and granularity to edit a particular shape as you would in Paint, but it’s a heck of a lot easier to use.  Although my knowledge is very limited in the area, I’m guessing you could make the same connection with C and C#.  C is a language (correct me if I’m wrong here) that is not designed for OOP, yet it allows you to reach the gutsy insides of a computer.  C# on the other-hand is designed to be used in OOP, and although it’s a lot harder to get to the lower-levels of computation, it is a lot faster, and ultimately easier to use.

Now jumping the gun a bit, it’s similar to Renderer and the toolkit.  Renderer is just a wrapper around OpenGl – it can do everything it wants, providing OpenGl supports it (although I haven’t wrapped around every single OpenGl call – that would be insane).  Yet if I were to use Renderer indirectly, via the toolkit, I am unable to do everything that Renderer supports – the toolkit limits my actions, yet makes the more commonly used functions of Renderer a lot easier to deal with.

Demo

Enough rambling.  I’ve implemented basic shapes in the toolkit, as well as very basic shape control.

Shapes.  Using the toolkit, I am able to ask for basic shapes.  Each shape has a fill colour, line colour and line width property.


Shapes Select.  I’ve also added picking functionality and shape control too.  When a user selects a fill/border of a shape, it will recognise it as a shape.  This is then decorated with a shape control.  This shape control has handles – these too are shapes.


Shapes Resize.  Clicking on a handle requires a couple of steps first before allowing to interact with it.  Although clicking on a border/fill will return the shape representing the handle, the handles act differently and need to be tested for.  Once this is done, we can notify the application that a handle is selected, not a shape.  This is important because if it was a shape, then the shape control will try to decorate the handle – clearly something that needs to be avoided.

Shapes Move.  clicking on a shape not only decorates it with a shape control, but it also allows you to drag and drop the shape too.


OOPhilosophy

Before this demo, I’ve had a lot of trouble creating similar objects. I’ve created bézier curves for the toolkit too, but I haven’t shown them because I ‘ve never been to happy with them.

If you recall from DrawCurve(Bézier);, near the end I was able to draw a master curve, encapsulating the bézier sub-curves.  To incorporate this into a scene graph, I needed an anchor, a node.  I did this by using a get property for the root of the curve.

public class Bezier : IRootNode
{
public Bezier()
{
RootNode = new Node(Matrix.Identity());
}

public INode RootNode { get; private set; }

private void CreateSubCurve()
{
var subCurve = new SubCurve();
RootNode.AddChild(subCurve.RootNode);
}

}

The problem with this is that once the Rootnode of the bézier curve is accessed, anything can be done with it.  A renderable can be assigned, all the children cleared, random children added.  It wasn’t very safe, and I never really did like it.

Why I never thought of simply inheriting from a model node in the first place, I’ll never know.  Not only does it allow me to change the node contents a lot easier, but it also means that I can change the interface, so that only a few select items can be modified.

public interface IShape
{
Colour FillColour { get; set; }
Colour BorderColour { get; set; }
double BorderThickness { get; set; }
}

internal class Shape : Node, IShape
{
public Shape(IFill fill, IBorder border) : base(Matrix.Identity())
{
Fill = fill;
Border = border;

base.AddChild((INode)Fill);
base.AddChild((INode)Border);
}

public Colour FillColour { get {…} set {…} }
public Colour BorderColour { get {…} set {…} }
public double BorderThickness { get {…} set {…} }

public IFill Fill { get; private set; }
public IBorder Border { get; private set; }

}

The only problem is that I have to cast from an IShape to an INode for when I want to add it to a graph, but at least the internals are protected from modification.  I suppose you could say someone could take an IShape and cast it into an INode and use it from there.  I guess there’s no stopping that.

Regardless, I’m finding it a lot easier to use the latter method than the former.  It took me only a week to create the shapes demo, but around two to get the bézier curves in the toolkit working.

Out of shape

Has anyone seen the statue designed for London 2012?  I thought I’d try and recreate it.  And if you ask me, I can’t say I’m particularly fond of it either.

Kapoor 2012.  Winning design for the London 2012 statue.  Apparently, it’s designed to stay.  No thanks.


OOP Kapoor 2012.  It might as well look like this.

As a side note, a couple of guys have released a rather nifty free tool, Paint.NET.  It’s a lightweight application that’s pretty much paint, but similar in the style and functionalities of Adobe Photoshop.  So those who can’t afford the extortionate prices of designer tools, well, I’d highly recommend giving it a try.   Did I also mention it’s free?

Posted in Computing, Placement | Tagged: , , , , , , , , , | Leave a Comment »