Planning the Spontaneous

It's more than just a blueprint.

Posts Tagged ‘Picking’

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.

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

Renderer: Demo

Posted by Robert Chow on 16/12/2009

So now that I’ve got a lot of my functionality going for me in this component, I thought I’d try and create a snazzy demo.

My supervisor’s obsessed with it. It’s like a little game – there is a rotating cube, and the challenge is you have to click on each face before you pass on to the next level. As you progress, the cube rotates just that little bit faster, making it harder to complete the challenge. Clicking on a face will turn that face on. Clicking on a face that is already on will turn it off – you can only progress when all 6 faces are switched on.

So you can automatically see that this little demo already involves the concept of vertex buffer objects (drawing of the cube), the scene graph (rotating cube), the camera (viewing the cube, using the scene graph) and picking (turning faces on/off). But what about the others?

Well, lets place the scene into dark surroundings – we’re going to need lights to see our cube – that’s lighting handled. So where does texturing fit in?

Switching the faces on/off need an indicator to show what state they are in.  We can easily do this by simply changing the colour of a face.  But that’s kinda boring.  So instead, we’re going to take the rendering to texture example, and slap that on a face which is on.  So that’s textures included.

Here are some screenshots of this demo.

Demo Setup. From left to right: initial scene – just a white cube; let’s dim the lighting to, well, none; include some lights: green – centre, red – bottom, blue – left; create a texture.

Demo Rotate. The demo in motion – the camera is stationary, whereas the cube is rotating, and the lights are rotating independantly around it.

Demo Play.  The first and second images show what happens when a face is clicked – the texture replaces the blank face.  Once all the faces are replaced with the texture, the demo advances to the next level.

Demo Camera.  This shows added functionality of how a camera can be fixed on to a light, thus the camera is rotating around the cube too.  Here it is fixed on to the blue light.  This is done with ease by manipulating the scene graph.

I guess you can’t really get a grasp of how this demo works in its entirety – sanpshots don’t really do it much justice.  I might try and upload a video or so – how, I’m unsure of – I’m sure I can probably find screen capture software around on the net.

And unfortunately, there is no score involved. Yet. That will come when fonts come.

Posted in Computing, Placement | Tagged: , , , , , , , , | 2 Comments »

Renderer: Picking

Posted by Robert Chow on 03/12/2009

Remember that decorator pattern I used for writing to textures?  Also particularly useful for picking too.

Decorate the main drawer class with a picking class.  This allows for the picking class to start off by setting up the render-mode to select mode, and to set the X and Y co-ordinates of the mouse.  Render the image as normal, but because of the render-mode switch, the image is rendered using the select buffer instead of the device context.  After this, the picking class is also able to interpret the picking buffer, and then return the results.

Sounds fairly easy.  But I did run into a problem near the start.

First off was the mouse wasn’t picking where I wanted – it was interpreting the mouse as always in the bottom-left hand corner.  Why so?

I later learnt that when changing the render-mode, it automatically multiplies the projection matrix by some pre-configured matrix so it can do the picking appropriately.  In the original drawer class, I was resetting the projection matrix by loading the identity, and thus wiping what the picker class had set up.  Kind of like defeating itself.  So I had to change this by taking the matrix resets out of the main drawing method, and place them outside – these would have to be called elsewhere – likely to be through the Renderer facade (another GoF pattern), before calling the draw.

So with the matrix set up properly, I did encounter another problem.  And this time it was hardware based.  It would pick appropiately on my supervisor’s computer, yet not on mine.

An example scenario:  there are several images overlapping each other, each with their own pick Id.

My supervisors computer: picks appropriately – returns the object with the nearest Z value (most positive), under mouse (X,Y) .

My computer: picks unappropriately – returns the object with the nearest Z value, under mouse(X,Y) – providing the object has not moved in modelview space in terms of the Z value.  This accounts for transformations, rotations and scales.  So therefore it will sometimes return the correct object, but most of the time, it won’t.  Particularly annoying if you have a scene that is constantly rotating, and you want to pick the nearest item – it will always pick the same item every single time, simply because it was rendered at the front first before it was rotated.

Simple fix:  enable culling.  This means that anything that is not in view won’t be rendered, so technically there is nothing behind the frontmost object – it can be the only one that is picked!

But that’s also particularly annoying when you want to use 2-face rendering.  This is the ability to render shapes clockwise, and counter-clockwise.  Enabling culling in OpenGL will result in all shapes that would originally be drawn clockwise to the screen, not drawn at all.  Not so useful in rotating scenes!

Anyway.

Combining textures and picking, this demo allows the user to pick a quadrant, and that will change accordingly – to texture if off, or to non-texture if on.

Renderer Picking Demo. From top-left, clockwise:  empty canvas; bottom-left quadrant click to turn texture on; top-right quadrant click to turn texture on; top-left quadrant click to turn texture on; bottom-left quadrant click to turn texture off; top-right quadrant click to turn texture off; bottom-right quadrant click to turn texture on; top-left quadrant click to turn texture off.  To achieve the original image from the last step, the user would click bottom-right quadrant, turning the texture off.

Posted in Computing, Placement | Tagged: , , , , , , , | 1 Comment »

enum Pick { Me, Me., Me! }

Posted by Robert Chow on 13/10/2009

So I’ve actually done quite a bit last week – true, I stayed in far longer than is starting to render as unhealthy, but there’s not much else to do is this place you call… Devon.

Picking

I started to look into picking – using the mouse, and being able to recognize what object I am hovering over.  It’s another thing that we all take for granted, but if it’s done incorrectly, it can be a huge nightmare.  You don’t really want to have to have your mouse 10 pixels to left of the object you want to select, and what’s worse is when there is an object behind another, and you can’t get to it, no matter how hard you try.  So I looked into it, and decided to combine it with the layering problem I had.  And I think I’ve got quite a lot of it sussed.

The picking is hardware based so you get all the hardware acceleration qualities – that’s a good thing.  The whole thing is essentially 2 processes.

1) Attach a number to an object, draw it, and repeat.
2) To find what you’ve clicked on, take the mouse position, change the render mode to select mode, and it should… hopefully… return the number you’ve assigned to the object you’ve clicked on.

Simples.

The code is below.  There’s not much to show, it really is quite simple!

We first set up the picking buffer – this stores the properties of the objects that have been picked – essentially every object under the cursor, regardless of visibility.  We must also set the mode – here RenderMode is used for reference.

PickBuffer = new int[PICKING_BUFFER_SIZE];
Gl.glSelectBuffer(PICKING_BUFFER_SIZE, PickBuffer);
RenderMode = Gl.GL_RENDER;

Wehn we come to render the scene, we check to see which mode we are in.  If it is the normal render mode, then render as normal… as it suggests.  If it’s in select mode, we have to take this into consideration, and set up the appropriate functions to allow the hardware to pick up what the mouse has just clicked on.  To do this, we only add a couple of lines – one of them sets up the pick matrix, and the other initializes the name stack that will allow you to assign a name to each object.  The viewport[] is the viewport you set normally, with viewport[3] being the height.  You can be lazy and get this from OpenGL by calling Gl.glGetIntegerv(Gl.GL_VIEWPORT, viewport). The picking tolerance are the x and y values of how big the surface your mouse should cover.

if (RenderMode == Gl.GL_SELECT)
{
Glu.gluPickMatrix(xmouse, (double)(viewport[3] -ymouse), PICKING_TOLERANCE, PICKING_TOLERANCE, viewport);
Gl.glInitNames();
Gl.glPushName(0xffffffff);
}

You can then render the scene, as per usual, but each time you draw an object, load a name to it by using a one call before drawing each object.  Note that name must be an integer value.

Gl.glLoadName(name);

Now for the interesting part!  As the mouse is clicked, make sure you set the mode to select mode.  Render the scene again, using the mouse x and y values, and hopefully, after all of this, you should have the number of items under the cursor – here as numberOfHits – and the pick buffer should be filled with the information regarding these objects.  There is a small glitch with OpenGL however regarding some graphics cards – it doesn’t register unless you double pick.  That’s easy to solve – just do it twice if at first you get no numberOfHits.

RenderMode = Gl.GL_SELECT;
Gl.glRenderMode(RenderMode);
RenderScene();
RenderMode = Gl.GL_RENDER;
int numberOfHits = Gl.glRenderMode(RenderMode);

Lastly, we sort out the information in the pick buffer.  The object that is directly visible under the cursor will be the last thing in the pick buffer.  What will end in pickedID will be the object name of what you’ve just clicked on!

for(int i = 0, index = 0; i < nHits; i++ )
{
int nItems = PickBuffer[index++];
int zMin = PickBuffer[index++];
int zMax = PickBuffer[index++];

for(int j = 0; j < nitems; j++ )
{
pickedID = PickBuffer[index++];
}
}

Simples!

EDIT:  Not so simple actually.  After trying picking on different computers, they each fill the pick buffer differently – I presume this is due to the fact that this picking is hardware based.  The best way to solve this is to enable GL_CULL_FACE.  That way, anything that is behind what you’ve picked won’t get rendered, and therefore your picking buffer will only hold the one item you’ve picked on.  (I think…)

 

Posted in Computing, Placement | Tagged: , , , , | 2 Comments »