SceneGraphDisplay bug fix

Apr 6, 2009 at 8:57 PM
A bug of SceneGraphDisplay has been fixed, and the fixed version SceneGraphDisplay1.0.1 has been uploaded. 

It used to have problem displaying nodes attached to MarkerNode, but now they are correctly displayed. 

Apr 23, 2009 at 11:26 AM
I downloaded the tool and was trying to include it in my project and in tutorial2 of Goblin, but i didn't manage to do it.

I followed the instructions in the user manual, but all I get is a bunch of nullpointerexceptions:

A first chance exception of type 'System.NullReferenceException' occurred in SceneGraphDisplay.dll
A first chance exception of type 'System.ArgumentNullException' occurred in System.Windows.Forms.dll
A first chance exception of type 'System.ArgumentNullException' occurred in System.Windows.Forms.dll
A first chance exception of type 'System.ArgumentNullException' occurred in System.Windows.Forms.dll

and it just goes on with these errors.

Has it happened to anyone?


Laetitia Mendes
Apr 26, 2009 at 5:04 PM
I've never seen first chance exception. What is your computer's specs? Can you run other XNA-only programs?
Apr 28, 2009 at 1:13 PM
I have an Intel Core 2 Duo,, 2.5GHz, 4GB RAM, WIndows Vista.

every XNA example runs perfectly.
I was wondering, do you have a simple example working , so I can compare? Maybe something is misplaced, or some spetial configurations is needed.

Thanks a lot (once again)

Laetitita Mendes
Apr 29, 2009 at 5:42 PM
I've attached the code for modified Tutorial2 that uses the SceneGraphDisplay tool.

Hope this helps.



public class Tutorial2 : Microsoft.Xna.Framework.Game
        GraphicsDeviceManager graphics;

        // A scene graph used to render virtual reality
        Scene scene;

        TransformNode torusTransParentNode;
        TransformNode shipTransParentNode;

        SpriteFont textFont;

        SGForm fs;

        // Boolean value to indicate whether 1st or 2nd animation sequence
        bool firstAnimation = true;
        double shipAngle = 0;
        double toriAngle = 0;

        public Tutorial2()
            graphics = new GraphicsDeviceManager(this);
            Content.RootDirectory = "Content";

        /// <summary>
        /// Allows the game to perform any initialization it needs to before starting to run.
        /// This is where it can query for any required services and load any non-graphic
        /// related content.  Calling base.Initialize will enumerate through any components
        /// and initialize them as well.
        /// </summary>
        protected override void Initialize()
            // Display the mouse cursor
            this.IsMouseVisible = true;

            // Initialize the GoblinXNA framework
            State.InitGoblin(graphics, Content, "");

            // Initialize the scene graph
            scene = new Scene(this);

            // Set the background color to CornflowerBlue color. 
            // GraphicsDevice.Clear(...) is called by Scene object with this color. 
            scene.BackgroundColor = Color.CornflowerBlue;

            // Set up the lights used in the scene

            // Set up the camera which defines the eye location and viewing frustum

            // Create 3D objects

            // Use per pixel lighting for better quality (If you using non NVidia graphics card,
            // setting this to true may reduce the performance significantly)
            scene.PreferPerPixelLighting = true;

            // Add a keyboard press handler for user input
            KeyboardInput.Instance.KeyPressEvent += new HandleKeyPress(KeyPressHandler);


        private void CreateLights()
            // Create two directional light sources
            LightSource lightSource1 = new LightSource();
            lightSource1.Direction = new Vector3(-1, -1, -1);
            lightSource1.Diffuse = Color.White.ToVector4();
            lightSource1.Specular = new Vector4(0.6f, 0.6f, 0.6f, 1);

            LightSource lightSource2 = new LightSource();
            lightSource2.Direction = new Vector3(0, 1, 0);
            lightSource2.Diffuse = Color.White.ToVector4()*.2f;
            lightSource2.Specular = new Vector4(0.2f, 0.2f, 0.2f, 1);

            // Create a light node to hold the light sources
            LightNode lightNode = new LightNode();

            // Add this light node to the root node

        private void CreateCamera()
            // Create a camera
            Camera camera = new Camera();
            // Put the camera at (-6, 0, 4)
            camera.Translation = new Vector3(-6, 0, 4);
            // Rotate the camera -20 degrees about the Y axis
            camera.Rotation = Quaternion.CreateFromAxisAngle(new Vector3(0, 1, 0),
            // Set the vertical field of view to be 60 degrees
            camera.FieldOfViewY = MathHelper.ToRadians(60);
            // Set the near clipping plane to be 0.1f unit away from the camera
            camera.ZNearPlane = 0.1f;
            // Set the far clipping plane to be 1000 units away from the camera
            camera.ZFarPlane = 1000;

            // Now assign this camera to a camera node, and add this camera node to our scene graph
            CameraNode cameraNode = new CameraNode(camera);

            // Assign the camera node to be our scene graph's current camera node
            scene.CameraNode = cameraNode;

        private void CreateObjects()
            // Loads a textured model of a ship
            ModelLoader loader = new ModelLoader();
            Model shipModel = (Model)loader.Load("", "p1_wedge");

            // Create a geometry node of a loaded ship model
            GeometryNode shipNode = new GeometryNode("Ship");
            shipNode.Model = shipModel;
            // This ship model has material definitions in the model file, so instead
            // of creating a material node for this ship model, we simply use its internal materials
            shipNode.Model.UseInternalMaterials = true;

            // Create a transform node to define the transformation for the ship
            TransformNode shipTransNode = new TransformNode();
            shipTransNode.Translation = new Vector3(0, 5, -12); 
            shipTransNode.Scale = new Vector3(0.002f, 0.002f, 0.002f); // It's huge!
            shipTransNode.Rotation = Quaternion.CreateFromAxisAngle(new Vector3(0, 1, 0),

            shipTransParentNode = new TransformNode();
            shipTransParentNode.Translation = Vector3.Zero;

            // Create a torus model and assign it to two geometry nodes
            Model torusModel = (Model)loader.Load("", "torus");// new Torus(2.2f, 3.5f, 30, 30);
            GeometryNode torusNode1 = new GeometryNode("Torus1");
            torusNode1.Model = torusModel;
            GeometryNode torusNode2 = new GeometryNode("Torus2");
            torusNode2.Model = torusModel;

            // Create transform node for these two torus models
            TransformNode torusTransNode1 = new TransformNode();
            torusTransNode1.Translation = new Vector3(5, 0, -12);

            TransformNode torusTransNode2 = new TransformNode();
            torusTransNode2.Translation = new Vector3(-5, 0, -12);

            torusTransParentNode = new TransformNode();
            torusTransParentNode.Translation = Vector3.Zero;

            // Create a material node for these two torus models
            Material torusMaterial = new Material();
            torusMaterial.Diffuse = Color.DarkGoldenrod.ToVector4();
            torusMaterial.Specular = Color.White.ToVector4();
            torusMaterial.SpecularPower = 5;

            // Now apply this material to these two torus models
            torusNode1.Material = torusMaterial;
            torusNode2.Material = torusMaterial;

            // Now add the above nodes to the scene graph in appropriate order


        private void KeyPressHandler(Keys keys, KeyModifier modifier)
            // Detect key press "a" (with or without a modifier) and toggle the animation
            if (keys == Keys.A)
                firstAnimation = !firstAnimation;

            if (keys == Keys.S)
                fs = new SGForm(scene);
                MouseInput.Instance.MouseClickEvent += new HandleMouseClick(fs.SG_MouseClickHandler);
                fs.Visible = true;

        /// <summary>
        /// LoadContent will be called once per game and is the place to load
        /// all of your content.
        /// </summary>
        protected override void LoadContent()
            textFont = Content.Load<SpriteFont>("Sample");

        /// <summary>
        /// UnloadContent will be called once per game and is the place to unload
        /// all content.
        /// </summary>
        protected override void UnloadContent()

        /// <summary>
        /// Allows the game to run logic such as updating the world,
        /// checking for collisions, gathering input, and playing audio.
        /// </summary>
        /// <param name="gameTime">Provides a snapshot of timing values.</param>
        protected override void Update(GameTime gameTime)
            if (firstAnimation)
                shipAngle += gameTime.ElapsedGameTime.TotalSeconds;
                // Rotate the ship model about the origin along Z axis
                shipTransParentNode.Rotation = Quaternion.CreateFromAxisAngle(Vector3.UnitZ, 
                toriAngle += gameTime.ElapsedGameTime.TotalSeconds;
                // Rotate the two torus models about the origin along Z axis
                torusTransParentNode.Rotation = Quaternion.CreateFromAxisAngle(Vector3.UnitZ,


        /// <summary>
        /// This is called when the game should draw itself.
        /// </summary>
        /// <param name="gameTime">Provides a snapshot of timing values.</param>
        protected override void Draw(GameTime gameTime)

            if (fs != null)

            // Draw a 2D text string at the center of the screen
            UI2DRenderer.WriteText(Vector2.Zero, "Press 'A' to toggle the animation!!", Color.GreenYellow,
Apr 29, 2009 at 6:43 PM
Edited Apr 29, 2009 at 6:47 PM
It does!!!

I mean, I still dont know what the problem was, but at least i have an example working!

Thanks very much =)

Laetitia Mendes