<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Scriptionary Blog &#187; graphics programming</title>
	<atom:link href="http://blog.scriptionary.com/tag/graphics-programming/feed/" rel="self" type="application/rss+xml" />
	<link>http://blog.scriptionary.com</link>
	<description>The informal yet informational sub-site</description>
	<lastBuildDate>Fri, 19 Feb 2010 16:21:55 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.9.2</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>Simple Scene Graph in C++</title>
		<link>http://blog.scriptionary.com/2009/02/17/simple-scene-graph-in-c/</link>
		<comments>http://blog.scriptionary.com/2009/02/17/simple-scene-graph-in-c/#comments</comments>
		<pubDate>Tue, 17 Feb 2009 20:07:15 +0000</pubDate>
		<dc:creator>Eddy Luten</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[C]]></category>
		<category><![CDATA[graphics programming]]></category>
		<category><![CDATA[snippets]]></category>

		<guid isPermaLink="false">http://blog.scriptionary.com/?p=68</guid>
		<description><![CDATA[There are several articles gathering dust bunnies on the internet on creating a scene graph class in C++ for your 3D engine but most are pretty vague and quite old. Hopefully, this post will give you a foot in the door in creating your own scene graph for your engine.
To start off, let&#8217;s go over [...]]]></description>
			<content:encoded><![CDATA[<p>There are several articles gathering dust bunnies on the internet on creating a scene graph class in C++ for your 3D engine but most are pretty vague and quite old. Hopefully, this post will give you a foot in the door in creating your own scene graph for your engine.</p>
<p>To start off, let&#8217;s go over some basics. A scene graph is a tree-like data structure which holds information about the scene you want to display. Every node has a parent and every node may have children. In this post we&#8217;ll use the std::vector to store the scene nodes but you can substitute this with whatever you want. A scene graph can be visualized like so:</p>
<pre>             [root node]
                  |
        o=========o=========o
        |         |         |
    [child 1] [child 2] [child 3]
        |
    o===o====o
    |        |
[child 4][child 5]
             |
         [child 6]</pre>
<p>Any node may have any number of children who&#8217;s children may have any number of children, etc. Each node in the scene graph may have a name for lookup functionality so a very lookup system will be implemented. We will also need functionality to add a child node, remove a child node, set/get a node&#8217;s parent and an update function for updating the graph hierarchically.<br />
<span id="more-68"></span><br />
Beware that this scene graph is for educational purposes <strong>only</strong>, I do not recommend that you implement this scene graph into your engine as it uses very simple algorithms and general-purpose classes from the C++ Standard Template Library. Also, keep in mind that <strong>a scene graph is not used for rendering your objects</strong>, it is used to keep hierarchical information and for applying hierarchical transformations.</p>
<p>Rendering your objects is done through a different type of structure such as a Binary Space Partitioning Tree (BSP-Tree) or an Octree which are structures more suitable for visibility testing and quite a bit faster. Your scene graph is updated each cycle of your simulation or game so that all the objects in your scene have their correct transformations.</p>
<p>Let&#8217;s start off with declaring our base class, the Node (below is the entire Node.h file):</p>
<pre style="overflow: auto; border: 1px solid silver; padding: 5px;">
#ifndef __node_h_
#define __node_h_ 1
#include &lt;vector&gt;

class Node
{
public:
	Node(Node* Parent = NULL, const char* Name = NULL);
	virtual ~Node(void);

	virtual void Update(void);

	Node* GetParentNode(void) const;
	void SetParentNode(Node* NewParent);

	void AddChildNode(Node* ChildNode);
	void RemoveChildNode(Node* ChildNode);

	const char* GetNodeName(void) const;
	const size_t CountChildNodes(const bool&amp; RecursiveCount = false) const;
	virtual const bool IsRootNode(void) const = 0;

	Node* GetChildNodeByName(const char* SearchName);

private:
	Node* m_Parent;
	const char* m_Name;
	std::vector&lt;Node*&gt; m_Children;

}; // class Node

#endif</pre>
<p>There are not many methods in this class so you have room for expansion if you feel like it. Beware that this class can only be used as a base class and cannot be initialized as <code>new Node()</code>. Let&#8217;s continue by examining the individual methods of this class:</p>
<p><strong>Node::Node(Node* Parent, const char* Name)</strong></p>
<pre style="overflow: auto; border: 1px solid silver; padding: 5px;">
Node::Node(Node* Parent, const char* Name)
	: m_Name(Name)
{
	m_Parent = Parent;
} // Constructor
</pre>
<p>As you can see I&#8217;ve kept the constructor very simple. The default for both parameters is <code>NULL</code> as both are optional. A node does not necessarily need a parent and a node does not require a name. You can of course change this by removing the <code>= NULL</code> sections out of the header file and throwing and exception if <code>NULL</code> was found in the source file.</p>
<hr style="width: 200px; margin: 10px auto;" />
<p><strong>Node::~Node(void)</strong></p>
<pre style="overflow: auto; border: 1px solid silver; padding: 5px;">
Node::~Node(void)
{
	m_Parent = NULL;
	m_Children.clear();
} // Destructor
</pre>
<p>The class destructor is also very simple, it simply sets the pointer to the parent node to <code>NULL</code> and clears the children-vector.</p>
<hr style="width: 200px; margin: 10px auto;" />
<p><strong>void Node::Update(void)</strong></p>
<pre style="overflow: auto; border: 1px solid silver; padding: 5px;">
void Node::Update(void)
{
	if(!m_Children.empty())
	{
		for(size_t i = 0; i &lt; m_Children.size(); ++i)
		{
			if(NULL != m_Children[i])
			{
				m_Children[i]-&gt;Update();
			}
		}
	}
} // Update()
</pre>
<p>Still pretty simple, this method goes through the children-vector and calls the Update method on each child that does not equal <code>NULL</code>. The child object in return calls the Update method so the behavior is recursive.</p>
<p>This method was designed to be overriden and called as <code>Node::Update()</code> by the overriding method.</p>
<hr style="width: 200px; margin: 10px auto;" />
<p><strong>Node* Node::GetParentNode(void) const</strong></p>
<pre style="overflow: auto; border: 1px solid silver; padding: 5px;">
Node* Node::GetParentNode(void) const
{
	return(m_Parent);
}; // GetParentNode()
</pre>
<p>A &#8220;property&#8221; which simply returns a pointer to the parent node.</p>
<hr style="width: 200px; margin: 10px auto;" />
<p><strong>void Node::SetParentNode(Node* NewParent)</strong></p>
<pre style="overflow: auto; border: 1px solid silver; padding: 5px;">
void Node::SetParentNode(Node* NewParent)
{
	if(NULL != m_Parent)
	{
		m_Parent-&gt;RemoveChildNode(this);
	}
	m_Parent = NewParent;
}; // SetParentNode()
</pre>
<p>This method sets a new parent node for the selected node and removes the node from the old parent node&#8217;s children-vector.</p>
<hr style="width: 200px; margin: 10px auto;" />
<p><strong>void Node::AddChildNode(Node* ChildNode)</strong></p>
<pre style="overflow: auto; border: 1px solid silver; padding: 5px;">
void Node::AddChildNode(Node* ChildNode)
{
	if(NULL != ChildNode)
	{
		if(NULL != ChildNode-&gt;GetParentNode())
		{
			ChildNode-&lt;SetParentNode(this);
		}
		m_Children.push_back(ChildNode);
	}
}; // AddChildNode()
</pre>
<p>Adds the node to the children-vector and updates the parent to the new parent if a parent was set.</p>
<hr style="width: 200px; margin: 10px auto;" />
<p><strong>void Node::RemoveChildNode(Node* ChildNode)</strong></p>
<pre style="overflow: auto; border: 1px solid silver; padding: 5px;">
void Node::RemoveChildNode(Node* ChildNode)
{
	if(NULL != ChildNode &amp;&amp; !m_Children.empty())
	{
		for(size_t i = 0; i &lt; m_Children.size(); ++i)
		{
			if(m_Children[i] == ChildNode)
			{
				m_Children.erase(m_Children.begin() + i);
				break; // break the for loop
			}
		}
	}
}; // RemoveChildNode()
</pre>
<p>This method loops through all of the child nodes and will remove the selected child node from the children-vector if found.</p>
<hr style="width: 200px; margin: 10px auto;" />
<p><strong>const char* Node::GetNodeName(void) const</strong></p>
<pre style="overflow: auto; border: 1px solid silver; padding: 5px;">
const char* Node::GetNodeName(void) const
{
	return(m_Name);
}; // GetNodeName()
</pre>
<p>A &#8220;property&#8221; which returns the name of the current node.</p>
<hr style="width: 200px; margin: 10px auto;" />
<p><strong>const size_t Node::CountChildNodes(const bool &#038;RecursiveCount) const</strong></p>
<pre style="overflow: auto; border: 1px solid silver; padding: 5px;">
const size_t Node::CountChildNodes(const bool &amp;RecursiveCount) const
{
	if(!RecursiveCount)
	{
		return(m_Children.size());
	}
	else
	{
		size_t Retval = m_Children.size();
		for(size_t i = 0; i &lt; m_Children.size(); ++i)
		{
			Retval += m_Children[i]-&gt;CountChildNodes(true);
		}
		return(Retval);
	}
}; // CountChildNodes()
</pre>
<p>Method counts all of the child nodes, recursive if required. If the recursive Boolean is set to true, the function will iterate over the entire hierarchy from the current node down and return a full node-count.</p>
<hr style="width: 200px; margin: 10px auto;" />
<p><strong>Node* Node::GetChildNodeByName(const char *SearchName)</strong></p>
<pre style="overflow: auto; border: 1px solid silver; padding: 5px;">
Node* Node::GetChildNodeByName(const char *SearchName)
{
	Node* Retval = NULL;
	if(!m_Children.empty())
	{
		for(size_t i = 0; i &lt; m_Children.size(); ++i)
		{
			if(0 == strcmp(m_Children[i]-&gt;m_Name, SearchName))
			{
				Retval = m_Children[i];
				break; // break the for loop
			}
		}
	}
	return(Retval);
}; // GetChildNodeByName()
</pre>
<p>This method will return a node referenced by name if it exists, otherwise it will return <code>NULL</code>. The function is fairly expensive and should be replaced with something more efficient but is fine for small trees and demos.</p>
<p><strong>Conclusion:</strong><br />
As you can see, the scene graph is quite simple but once you understand how to implement one customization isn&#8217;t hard. Things you might want to change are passing a time value to the Update() method of Node so that your nodes may have a notion of time passed between calls, something faster than std::vector for storage and implementing a type-checking mechanism.</p>
<p>Regardless of the above, if you&#8217;re slapping together a quick demo that&#8217;s not performance sensitive the code with tweaks should do fine. <span style="background: #FFE;">Let me know if I missed or something or screwed something up since this post has been sitting in limbo for quite a while.</span></p>
]]></content:encoded>
			<wfw:commentRss>http://blog.scriptionary.com/2009/02/17/simple-scene-graph-in-c/feed/</wfw:commentRss>
		<slash:comments>7</slash:comments>
		</item>
		<item>
		<title>Getting there</title>
		<link>http://blog.scriptionary.com/2008/03/23/getting-there/</link>
		<comments>http://blog.scriptionary.com/2008/03/23/getting-there/#comments</comments>
		<pubDate>Sun, 23 Mar 2008 21:30:58 +0000</pubDate>
		<dc:creator>Eddy Luten</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[graphics programming]]></category>
		<category><![CDATA[Win32]]></category>

		<guid isPermaLink="false">http://blog.scriptionary.com/2008/03/23/getting-there/</guid>
		<description><![CDATA[Scriptionary is growing again. Several articles have been added to the Wiki and a few articles are still coming up. Notably, two articles have been recovered from the old site: Got a minute? Refactor your code and CPUs Maximum Throughput and Overhead which haven&#8217;t been altered from their original formats.
Besides the old, new things have [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://scriptionary.com/">Scriptionary</a> is growing again. Several articles have been added to the Wiki and a few articles are still coming up. Notably, two articles have been recovered from the old site: <a href="http://scriptionary.com/Got_a_minute%3F_Refactor_your_code">Got a minute? Refactor your code</a> and <a href="http://scriptionary.com/CPUs_Maximum_Throughput_and_Overhead">CPUs Maximum Throughput and Overhead</a> which haven&#8217;t been altered from their original formats.</p>
<p>Besides the old, new things have been introduced to Scriptionary such as the <a href="http://scriptionary.com/Creating_a_Window_Wrapper_Class" title="Creating a Window Wrapper Class">Creating a Window Wrapper Class</a> and <a href="http://scriptionary.com/Getting_Screen_Modes" title="Getting Screen Modes">Getting Screen Modes</a> articles for Microsoft Windows Graphics Programmers.</p>
<p><strong>Edit:</strong> Additionally, you can keep track of the pages by visiting the <a href="http://scriptionary.com/Special:Allpages">&#8220;All Pages&#8221; page</a> on the wiki.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.scriptionary.com/2008/03/23/getting-there/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
