<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:georss='http://www.georss.org/georss' xmlns:gd='http://schemas.google.com/g/2005' xmlns:thr='http://purl.org/syndication/thread/1.0'><id>tag:blogger.com,1999:blog-2766425237491213801</id><updated>2012-01-09T08:46:08.840Z</updated><category term='C++'/><category term='procedural planet'/><category term='decade'/><category term='modelview'/><category term='opengl'/><category term='matrix'/><category term='game'/><category term='backface culling'/><title type='text'>Decade Engine</title><subtitle type='html'></subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://decadeengine.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2766425237491213801/posts/default?max-results=100'/><link rel='alternate' type='text/html' href='http://decadeengine.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><author><name>Ciarán McCormack</name><uri>http://www.blogger.com/profile/12300242420318331807</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>62</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>100</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-2766425237491213801.post-8772894846560434867</id><published>2011-11-01T10:58:00.000Z</published><updated>2011-11-01T10:58:29.946Z</updated><title type='text'>How to generate a procedural sphere.</title><content type='html'>I have received an email asking to explain how I generate a procedural sphere as per this &lt;a href="http://decadeengine.blogspot.com/2007/10/procedural-sphere.html"&gt;post&lt;/a&gt;. Rather than respond to emails personally, I have decide in future to answer the questions on the blog, presenting the information to a wider audience for comment, correction, improvement and perhaps a little learning.&lt;br /&gt;&lt;br /&gt;The base of my generated sphere is a cube. Depending on how smooth the generated sphere needs to be, I recursively split each side into 4 equally sized children. This is achieved my finding the center of the face, popping that point out so that it is the correct radius from the center, then making 4 faces using the original points and this new point. (There is some ASCII art showing this in the code below)&lt;br /&gt;&lt;br /&gt;&lt;span style="color: blue;"&gt;void &lt;/span&gt;CSphere::Initialize(&lt;span style="color: blue;"&gt;float &lt;/span&gt;p_fRadius, &lt;span style="color: blue;"&gt;int &lt;/span&gt;p_iMaxDepth)&lt;br /&gt;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: #38761d;"&gt;//&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; TLB----TRB&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;br style="color: #38761d;" /&gt;&lt;span style="color: #38761d;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; //&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; /|&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; /|&lt;/span&gt;&lt;br style="color: #38761d;" /&gt;&lt;span style="color: #38761d;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; //&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; /&amp;nbsp; |&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; /&amp;nbsp; |&lt;/span&gt;&lt;br style="color: #38761d;" /&gt;&lt;span style="color: #38761d;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; //&amp;nbsp;&amp;nbsp;&amp;nbsp; TLF----TRF&amp;nbsp;&amp;nbsp;&amp;nbsp; |&lt;/span&gt;&lt;br style="color: #38761d;" /&gt;&lt;span style="color: #38761d;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; //&amp;nbsp;&amp;nbsp;&amp;nbsp; |&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; BLB--|BRB&lt;/span&gt;&lt;br style="color: #38761d;" /&gt;&lt;span style="color: #38761d;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; //&amp;nbsp;&amp;nbsp;&amp;nbsp; |&amp;nbsp;&amp;nbsp; /&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; |&amp;nbsp; /&lt;/span&gt;&lt;br style="color: #38761d;" /&gt;&lt;span style="color: #38761d;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; //&amp;nbsp;&amp;nbsp;&amp;nbsp; | /&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; |/&lt;/span&gt;&lt;br style="color: #38761d;" /&gt;&lt;span style="color: #38761d;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; //&amp;nbsp;&amp;nbsp;&amp;nbsp; BLF----BRF&lt;/span&gt;&lt;br style="color: #38761d;" /&gt;&lt;br style="color: #38761d;" /&gt;&lt;span style="color: #38761d;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; //Putting the Vertices of the initial Cube at p_fRadius is not correct as the distance of&lt;/span&gt;&lt;br style="color: #38761d;" /&gt;&lt;span style="color: #38761d;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; //p_fRadius, p_fRadius, p_fRadius from the Origin is greater than p_fRadius.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; CVector3 l_Vertices[8];&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; l_Vertices[TOP_LEFT_FRONT] = MoveToRadiusDistance(CVector3(-p_fRadius,&amp;nbsp; p_fRadius, -p_fRadius), p_fRadius);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; l_Vertices[TOP_RIGHT_FRONT] = MoveToRadiusDistance(CVector3( p_fRadius,&amp;nbsp; p_fRadius, -p_fRadius), p_fRadius);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; l_Vertices[BOTTOM_RIGHT_FRONT] = MoveToRadiusDistance(CVector3( p_fRadius, -p_fRadius, -p_fRadius), p_fRadius);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; l_Vertices[BOTTOM_LEFT_FRONT] = MoveToRadiusDistance(CVector3(-p_fRadius, -p_fRadius, -p_fRadius), p_fRadius);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; l_Vertices[TOP_LEFT_BACK] = MoveToRadiusDistance(CVector3(-p_fRadius,&amp;nbsp; p_fRadius,&amp;nbsp; p_fRadius), p_fRadius);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; l_Vertices[TOP_RIGHT_BACK] = MoveToRadiusDistance(CVector3( p_fRadius,&amp;nbsp; p_fRadius,&amp;nbsp; p_fRadius), p_fRadius);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; l_Vertices[BOTTOM_RIGHT_BACK] = MoveToRadiusDistance(CVector3( p_fRadius, -p_fRadius,&amp;nbsp; p_fRadius), p_fRadius);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; l_Vertices[BOTTOM_LEFT_BACK] = MoveToRadiusDistance(CVector3(-p_fRadius, -p_fRadius,&amp;nbsp; p_fRadius), p_fRadius);&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: #38761d;"&gt; //Initialize the faces of the cube (The face structure just stores the vertices for the face corners and has render functionality, not applicable to this explanation, and its depth in the face tree)&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; m_pFaces[FRONT].Initialise(FRONT, l_Vertices[TOP_LEFT_FRONT], l_Vertices[TOP_RIGHT_FRONT], l_Vertices[BOTTOM_RIGHT_FRONT], l_Vertices[BOTTOM_LEFT_FRONT], DEPTH0);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; m_pFaces[RIGHT].Initialise(RIGHT, l_Vertices[TOP_RIGHT_FRONT], l_Vertices[TOP_RIGHT_BACK], l_Vertices[BOTTOM_RIGHT_BACK], l_Vertices[BOTTOM_RIGHT_FRONT], DEPTH0);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; m_pFaces[BACK].Initialise(BACK, l_Vertices[TOP_RIGHT_BACK], l_Vertices[TOP_LEFT_BACK], l_Vertices[BOTTOM_LEFT_BACK], l_Vertices[BOTTOM_RIGHT_BACK], DEPTH0);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; m_pFaces[LEFT].Initialise(LEFT, l_Vertices[TOP_LEFT_BACK], l_Vertices[TOP_LEFT_FRONT], l_Vertices[BOTTOM_LEFT_FRONT], l_Vertices[BOTTOM_LEFT_BACK], DEPTH0);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; m_pFaces[TOP].Initialise(TOP, l_Vertices[TOP_LEFT_BACK], l_Vertices[TOP_RIGHT_BACK], l_Vertices[TOP_RIGHT_FRONT], l_Vertices[TOP_LEFT_FRONT], DEPTH0);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; m_pFaces[BOTTOM].Initialise(BOTTOM, l_Vertices[BOTTOM_LEFT_FRONT], l_Vertices[BOTTOM_RIGHT_FRONT], l_Vertices[BOTTOM_RIGHT_BACK], l_Vertices[BOTTOM_LEFT_BACK], DEPTH0);&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="background-color: white; color: #38761d;"&gt;//Subdivide each patch to the lowest resolution&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; m_pPatches[FRONT].SubDivide(p_fRadius, p_iMaxDepth);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; m_pPatches[RIGHT].SubDivide(p_fRadius, p_iMaxDepth);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; m_pPatches[BACK].SubDivide(p_fRadius, p_iMaxDepth);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; m_pPatches[LEFT].SubDivide(p_fRadius, p_iMaxDepth);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; m_pPatches[TOP].SubDivide(p_fRadius, p_iMaxDepth);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; m_pPatches[BOTTOM].SubDivide(p_fRadius, p_iMaxDepth);&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;where&lt;br /&gt;&lt;br /&gt;&lt;span style="color: blue;"&gt;bool &lt;/span&gt;CSphereFace::SubDivide(float p_fRadius, int p_iMaxDepth)&lt;br /&gt;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;if&lt;/span&gt; (m_iDepth &amp;gt;= p_iMaxDepth)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: blue;"&gt; return false&lt;/span&gt;;&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: #38761d;"&gt; //Create the Additional Vertices&lt;/span&gt;&lt;span style="color: #38761d;"&gt;&lt;/span&gt;&lt;br style="color: #38761d;" /&gt;&lt;span style="color: #38761d;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; //&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;br style="color: #38761d;" /&gt;&lt;span style="color: #38761d;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; //&amp;nbsp;&amp;nbsp;&amp;nbsp; NW---------------D-------------NE&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;br style="color: #38761d;" /&gt;&lt;span style="color: #38761d;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; //&amp;nbsp;&amp;nbsp;&amp;nbsp; |&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; |&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; |&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;br style="color: #38761d;" /&gt;&lt;span style="color: #38761d;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; //&amp;nbsp;&amp;nbsp;&amp;nbsp; |&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; |&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; |&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;br style="color: #38761d;" /&gt;&lt;span style="color: #38761d;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; //&amp;nbsp;&amp;nbsp;&amp;nbsp; |&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; |&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; |&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;br style="color: #38761d;" /&gt;&lt;span style="color: #38761d;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; //&amp;nbsp;&amp;nbsp;&amp;nbsp; |&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; |&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; |&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;br style="color: #38761d;" /&gt;&lt;span style="color: #38761d;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; //&amp;nbsp;&amp;nbsp;&amp;nbsp; A--------------Center-----------C&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;br style="color: #38761d;" /&gt;&lt;span style="color: #38761d;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; //&amp;nbsp;&amp;nbsp;&amp;nbsp; |&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; |&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; |&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;br style="color: #38761d;" /&gt;&lt;span style="color: #38761d;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; //&amp;nbsp;&amp;nbsp;&amp;nbsp; |&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; |&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; |&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;br style="color: #38761d;" /&gt;&lt;span style="color: #38761d;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; //&amp;nbsp;&amp;nbsp;&amp;nbsp; |&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; |&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; |&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;br style="color: #38761d;" /&gt;&lt;span style="color: #38761d;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; //&amp;nbsp;&amp;nbsp;&amp;nbsp; |&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; |&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; |&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;br style="color: #38761d;" /&gt;&lt;span style="color: #38761d;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; //&amp;nbsp;&amp;nbsp;&amp;nbsp; SW----------------B-------------SE&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;br style="color: #38761d;" /&gt;&lt;span style="color: #38761d;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; //&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;br style="color: #38761d;" /&gt;&lt;span style="color: #38761d;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; //&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; g_vAdditionalVertices[A] = m_vBaseVertices[eNorthWest] + ((m_vBaseVertices[eSouthWest] - m_vBaseVertices[eNorthWest]) / 2.0f);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; g_vAdditionalVertices[B] = m_vBaseVertices[eSouthWest] + ((m_vBaseVertices[eSouthEast] - m_vBaseVertices[eSouthWest]) / 2.0f);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; g_vAdditionalVertices[C] = m_vBaseVertices[eNorthEast] + ((m_vBaseVertices[eSouthEast] - m_vBaseVertices[eNorthEast]) / 2.0f);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; g_vAdditionalVertices[D] = m_vBaseVertices[eNorthWest] + ((m_vBaseVertices[eNorthEast] - m_vBaseVertices[eNorthWest]) / 2.0f);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: #38761d;"&gt;//Create Child Nodes&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; m_pChildren = new CSphereFace[4];&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; m_pChildren[eNorthWest].Initialise(eNorthWest, m_vBaseVertices[eNorthWest], g_vAdditionalVertices[D], m_vBaseVertices[eCentre], g_vAdditionalVertices[A], m_iDepth + 1);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; m_pChildren[eNorthEast].Initialise(eNorthEast, g_vAdditionalVertices[D], m_vBaseVertices[eNorthEast], g_vAdditionalVertices[C], m_vBaseVertices[eCentre], m_iDepth + 1);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; m_pChildren[eSouthWest].Initialise(eSouthWest, g_vAdditionalVertices[A], m_vBaseVertices[eCentre], g_vAdditionalVertices[B], m_vBaseVertices[eSouthWest], m_iDepth + 1);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; m_pChildren[eSouthEast].Initialise(eSouthEast, m_vBaseVertices[eCentre], g_vAdditionalVertices[C], m_vBaseVertices[eSouthEast], g_vAdditionalVertices[B], m_iDepth + 1);&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; m_pChildren[eNorthWest].SubDivide(p_fRadius, p_iMaxDepth);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; m_pChildren[eNorthEast].SubDivide(p_fRadius, p_iMaxDepth);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; m_pChildren[eSouthWest].SubDivide(p_fRadius, p_iMaxDepth);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; m_pChildren[eSouthEast].SubDivide(p_fRadius, p_iMaxDepth);&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;return true&lt;/span&gt;;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;and&lt;br /&gt;&lt;br /&gt;CVector3 MoveToRadiusDistance(CVector3 p_Vector, &lt;span style="color: blue;"&gt;float &lt;/span&gt;p_fRadius)&lt;br /&gt;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; &lt;span style="color: #38761d;"&gt;//Get the Normalized Vector, of this vertex from the origin (center of the sphere) and pop it out to the correct radius,&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;return &lt;/span&gt;p_Vector.Normalize() * p_fRadius;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;That is pretty much the basics of how I create the sphere from recursively subdividing a cube. If I overlooked anything please comment and I will correct the post to reflect any gap in information or any mistake.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2766425237491213801-8772894846560434867?l=decadeengine.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://decadeengine.blogspot.com/feeds/8772894846560434867/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://decadeengine.blogspot.com/2011/11/how-to-generate-procedural-sphere.html#comment-form' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2766425237491213801/posts/default/8772894846560434867'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2766425237491213801/posts/default/8772894846560434867'/><link rel='alternate' type='text/html' href='http://decadeengine.blogspot.com/2011/11/how-to-generate-procedural-sphere.html' title='How to generate a procedural sphere.'/><author><name>Ciarán McCormack</name><uri>http://www.blogger.com/profile/12300242420318331807</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2766425237491213801.post-8668537567317569811</id><published>2011-05-07T16:53:00.001+01:00</published><updated>2011-05-08T03:48:39.323+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='procedural planet'/><category scheme='http://www.blogger.com/atom/ns#' term='opengl'/><category scheme='http://www.blogger.com/atom/ns#' term='C++'/><category scheme='http://www.blogger.com/atom/ns#' term='decade'/><category scheme='http://www.blogger.com/atom/ns#' term='game'/><title type='text'>Can I claim progress even if I am behind where I used be?</title><content type='html'>I am the first to admit annoyance at having to redo functionality which I have previously implemented, however with the experience and lessons learned when coding procedural planets the first time, my implementation this time is smaller (in code) and more efficient than before.&lt;br /&gt;&lt;br /&gt;I shall try and highlight an area which is&lt;br /&gt;&lt;ol&gt;&lt;li&gt; Easier to implement&lt;/li&gt;&lt;li&gt;Less code&lt;/li&gt;&lt;li&gt;More efficient&lt;/li&gt;&lt;/ol&gt;From the centre of LOD (Level of Detail) every patch within a certain distance is rendered at the same LOD. The previous version of Decade calculated the distance from the centre of the patching being tested to the centre of LOD. The length between two positions in 3D space is calculated as&lt;br /&gt;&lt;br /&gt;&lt;span style="color: blue;"&gt;#define&lt;/span&gt; SQUARE(x)&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; ((x)*(x))&lt;br /&gt;&lt;br /&gt;&lt;span style="color: blue;"&gt;float &lt;/span&gt;Length(CVector3* p_pvOne, CVector3* p_pvTwo)&lt;br /&gt;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;return &lt;/span&gt;(&lt;span style="color: blue;"&gt;float&lt;/span&gt;)(sqrt(SQUARE(pvTwo-&amp;gt;X - p_pvOne-&amp;gt;X) + SQUARE(pvTwo-&amp;gt;Y - p_pvOne-&amp;gt;Y) + SQUARE(pvTwo-&amp;gt;Z - p_pvOne-&amp;gt;Z)));&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;(The &lt;i&gt;sqrt &lt;/i&gt;function has been traditionally considered slow and avoided if possible. I am unsure of its performance on modern hardware however the above could be optimised by not calculating the sqrt in the length function, and comparing it to the expected value squared.)&lt;br /&gt;&lt;br /&gt;An better optimisation is to remove the requirement for calculating the distance from each patch to the centre of LOD completely. Instead of using the distance from the centre, I now recursively step from the centre to each neighbour, then onto each of their neighbours while incrementing the 'distance' with each step. When the 'distance' reaches a predefined value, the edge of the LOD area has been reached. In the following images 'distance limit' is set to 3.&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://2.bp.blogspot.com/-OSG0Ev3imlM/TcVkCHc_dzI/AAAAAAAAAZE/dFNtfuopiVg/s1600/wrong.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="252" src="http://2.bp.blogspot.com/-OSG0Ev3imlM/TcVkCHc_dzI/AAAAAAAAAZE/dFNtfuopiVg/s320/wrong.jpg" width="320" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;The results above are not as desired. Some analysis showed that the east and west neighbours of the centre of LOD are within 3 recursive steps from the north neighbour (which is processed first). Because of this the east and west patches are marked as processed and will not be processed again when directly updated from the centre patch.&lt;br /&gt;&lt;br /&gt;To overcome this, when processing a patch, if it is already flagged as processed, I compare its distance in steps from the centre of LOD. If the current distance is less than the stored distance I process again. Reading that sounds a little confusing so I shall try and explain in some steps. (only key steps are listed)&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Move from the centre patch to the north. Its distance is stored as 1&lt;/li&gt;&lt;li&gt;Move from the current patch (north) to the east. Distance is stored as 2&lt;/li&gt;&lt;li&gt;Move from the current patch (north-&amp;gt;east) to the south (this is the centres east neighbour). Distance is stored as 3.&lt;/li&gt;&lt;li&gt;Move from the centre patch to the east. This patch is flagged as  processed at a distance of 3. The current distance is 1 therefore ignore  previous processing and process again.&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://2.bp.blogspot.com/-a-KGcpgxSw8/TcVmmWo-hVI/AAAAAAAAAZI/1qzs2RL_4Vw/s1600/intermediate.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="253" src="http://2.bp.blogspot.com/-a-KGcpgxSw8/TcVmmWo-hVI/AAAAAAAAAZI/1qzs2RL_4Vw/s320/intermediate.jpg" width="320" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: left;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: left;"&gt;That looks better. It is a uniform area around the centre of LOD. However, it is  still not correct. To render the next area of lower LOD I step 1 level  up the patch tree and render outwards from here. Patches are not  rendered if any of its children have been rendered as this would cause  an unacceptable overlap and possible onscreen artifacts. This results in  huge holes in the terrain.&lt;/div&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://3.bp.blogspot.com/-VMyHG_Un7hM/TcVnhZ7rgYI/AAAAAAAAAZM/USXeq8_GKBQ/s1600/intermediate2.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="253" src="http://3.bp.blogspot.com/-VMyHG_Un7hM/TcVnhZ7rgYI/AAAAAAAAAZM/USXeq8_GKBQ/s320/intermediate2.jpg" width="320" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://3.bp.blogspot.com/-VMyHG_Un7hM/TcVnhZ7rgYI/AAAAAAAAAZM/USXeq8_GKBQ/s1600/intermediate2.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;br /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: left;"&gt;&lt;br /&gt;&lt;/div&gt;A simple rule of "if one of my siblings is being rendered at a specific LOD, I must also render at that LOD even if I am not within range of the centre of LOD" fixes this problem.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://2.bp.blogspot.com/-L-N7UUK76So/TcVoZhVyiuI/AAAAAAAAAZQ/DM3-42MAgwg/s1600/correct.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="252" src="http://2.bp.blogspot.com/-L-N7UUK76So/TcVoZhVyiuI/AAAAAAAAAZQ/DM3-42MAgwg/s320/correct.jpg" width="320" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;The above example has resulted in code which is smaller, simpler to understand and faster to run than the previous version based on actual distance.&lt;br /&gt;&lt;br /&gt;&lt;table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td style="text-align: center;"&gt;&lt;a href="http://2.bp.blogspot.com/-ZU6g9MZSS14/TcVpu7t7mZI/AAAAAAAAAZU/dr812XvOHls/s1600/one.jpg" imageanchor="1" style="margin-left: auto; margin-right: auto;"&gt;&lt;img border="0" height="251" src="http://2.bp.blogspot.com/-ZU6g9MZSS14/TcVpu7t7mZI/AAAAAAAAAZU/dr812XvOHls/s320/one.jpg" width="320" /&gt;&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="tr-caption" style="text-align: center;"&gt;Planet rendered from orbit showing LOD&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td style="text-align: center;"&gt;&lt;a href="http://2.bp.blogspot.com/-K6rcDZUjgNQ/TcVqI0GxfII/AAAAAAAAAZY/i2faJ0MUosw/s1600/two.jpg" imageanchor="1" style="margin-left: auto; margin-right: auto;"&gt;&lt;img border="0" height="252" src="http://2.bp.blogspot.com/-K6rcDZUjgNQ/TcVqI0GxfII/AAAAAAAAAZY/i2faJ0MUosw/s320/two.jpg" width="320" /&gt;&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="tr-caption" style="text-align: center;"&gt;Same planet rendered from atmosphere, again showing LOD&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2766425237491213801-8668537567317569811?l=decadeengine.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://decadeengine.blogspot.com/feeds/8668537567317569811/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://decadeengine.blogspot.com/2011/05/can-i-claim-progress-even-if-i-am.html#comment-form' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2766425237491213801/posts/default/8668537567317569811'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2766425237491213801/posts/default/8668537567317569811'/><link rel='alternate' type='text/html' href='http://decadeengine.blogspot.com/2011/05/can-i-claim-progress-even-if-i-am.html' title='Can I claim progress even if I am behind where I used be?'/><author><name>Ciarán McCormack</name><uri>http://www.blogger.com/profile/12300242420318331807</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://2.bp.blogspot.com/-OSG0Ev3imlM/TcVkCHc_dzI/AAAAAAAAAZE/dFNtfuopiVg/s72-c/wrong.jpg' height='72' width='72'/><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2766425237491213801.post-4521361089790290449</id><published>2011-03-28T12:39:00.002+01:00</published><updated>2011-03-28T12:50:25.562+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='backface culling'/><category scheme='http://www.blogger.com/atom/ns#' term='procedural planet'/><category scheme='http://www.blogger.com/atom/ns#' term='modelview'/><category scheme='http://www.blogger.com/atom/ns#' term='matrix'/><title type='text'>Remove back facing patches before the render pipeline.</title><content type='html'>&lt;div style="text-align: left;"&gt;&lt;/div&gt;&lt;div style="text-align: left;"&gt;In a previous post, &lt;a href="http://decadeengine.blogspot.com/2010/01/procedural-planet-subdividing-cube.html"&gt;Procedural Planet - Subdividing Cube &lt;/a&gt;I  mentioned how I remove complete patches which are facing away from the  camera before the API culled their polygons in the render pipeline. &lt;br /&gt;&lt;br /&gt;&lt;i&gt;"Using frustum culling is not enough to remove any unrendered  polygons from the planet. When close to a planet it can look like a flat  terrain, just like the earth does for us as we stand on it, but from  height it can be seen that the planet is in-fact spherical. With this  knowledge it is possible to mathematically remove allot of the planet  patches which are on the opposite side of the planet. With Back face  culling the API would remove these anyway, however it would be very  wasteful to pass these invisible faces down the render pipeline. By  using a DotProduct with the LookAt vector of the camera and the Normal  of the planet patch translated to model space, it is very simple to  ignore these patches."&lt;/i&gt;&lt;br /&gt;&lt;br /&gt;This code was part of what was lost from Decade with the recient SVN  blooper, and therefore had to be rewritten. Despite having implemented  the functionality about 18 months ago it took me some time to grasp the  idea. I feel that a more technical post would be useful and will  hopefully help anyone else when implementing similar functionality.&lt;br /&gt;&lt;br /&gt;Anyone with experience in graphics programming will be familar with the  concept of backface culling. As each polygon is passed down the  rendering pipeline, it is tested to see if it is facing torwards or away  from the camera. Since polygons facing away from the camera cannot be  seen there is no need to render them. This concept can be applied when  rendering a planet, however instead of just testing on a polygon by  polygon basis, I test patch by patch. This allows me to ignore large  collections of polygons with 1 test instead of the previously described  polygon test.&lt;br /&gt;&lt;br /&gt;How is this achieved?&lt;br /&gt;&lt;br /&gt;Two pieces of information are required in order to test if a patch is facing towards or away from the camera.&lt;br /&gt;&lt;br /&gt;1) The camera look-at vector. This is maintained by the camera object  and updated as the camera moves and rotates around the world.&lt;br /&gt;2) The normal vector of the patch. I calculate this when the patch is  created by doing a CrossProduct of the vectors of 2 sides of the patch.&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://4.bp.blogspot.com/-78XSmOD5nDE/TZBwzrTJVPI/AAAAAAAAAYw/BiNNwg8Hm4M/s1600/PlanetPatch_withnormal.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="320" src="http://4.bp.blogspot.com/-78XSmOD5nDE/TZBwzrTJVPI/AAAAAAAAAYw/BiNNwg8Hm4M/s320/PlanetPatch_withnormal.jpg" width="271" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;If the values of A,B,C and D in the above image are&lt;br /&gt;&lt;br /&gt;l_vA: X=-11.547007 Y=11.547007 Z=-11.547007&lt;br /&gt;l_vB: X=-6.6666670 Y=13.333334 Z=-13.333334&lt;br /&gt;l_vC: X=-8.1649666 Y=8.1649666 Z=-16.329933&lt;br /&gt;l_vD: X=-13.333334 Y=6.6666670 Z=-13.333334&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;The normal of the patch can be calculated using the following code.&lt;br /&gt;&lt;br /&gt;m_vNormal = CalculateNormal(l_vB, l_vA, l_vC);&lt;br /&gt;&lt;br /&gt;where&lt;br /&gt;&lt;br /&gt;CVector3 CalculateNormal(CVector3 p_vOne, CVector3 p_vTwo, CVector3 p_vThree)&lt;br /&gt;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; CVector3 l_vA = p_vTwo - p_vOne;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; CVector3 l_vB = p_vThree - p_vOne;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;return&lt;/span&gt; Normalize(CrossProduct(l_vA, l_vB));&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;CVector3 CrossProduct(CVector3 p_vVectorOne, CVector3 p_vVectorTwo)&lt;br /&gt;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; CVector3 l_vResult;&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; l_vResult.X = p_vVectorOne.Y * p_vVectorTwo.Z - p_vVectorOne.Z * p_vVectorTwo.Y;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; l_vResult.Y = p_vVectorOne.Z * p_vVectorTwo.X - p_vVectorOne.X * p_vVectorTwo.Z;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; l_vResult.Z = p_vVectorOne.X * p_vVectorTwo.Y - p_vVectorOne.Y * p_vVectorTwo.X;&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;return&lt;/span&gt; l_vResult;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;The calculated normal would be X=0.44721335 Y=-0.44721335 Z=0.77459687&lt;br /&gt;&lt;br /&gt;With this information, as each patch is rendered, a simple DotProduct of these 2 pieces of information returns a floating point value. If this value is less than 0, the patch is facing away from the camera and therefore it and all its child patches can immediately be discarded.&lt;br /&gt;&lt;br /&gt;&lt;span style="color: blue;"&gt;float&lt;/span&gt; l_fDotProduct =&amp;nbsp; DotProduct(m_vNormal, p_pCamera-&amp;gt;get_LookAt());&lt;br /&gt;&lt;span style="color: blue;"&gt;if&lt;/span&gt; (0.0f &amp;gt; l_fDotProduct)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;return&lt;/span&gt;;&lt;br /&gt;&lt;br /&gt;where &lt;br /&gt;&lt;br /&gt;&lt;span style="color: blue;"&gt;float &lt;/span&gt;DotProduct(CVector3 p_vVectorOne, CVector3 p_vVectorTwo)&lt;br /&gt;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;return &lt;/span&gt;p_vVectorTwo.X * p_vVectorOne.X + p_vVectorTwo.Y * p_vVectorOne.Y + p_vVectorTwo.Z * p_vVectorOne.Z;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;One more issue must be dealt with before we have a complete solution. The above works well for static objects where all vertices are relative to the origin. However what will happen if the object is rotating?&lt;br /&gt;The answer of that question is shown in the following image.&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://2.bp.blogspot.com/-wt-0Xqy0VnM/TZBysRtoVDI/AAAAAAAAAY0/Yd3SUw3avM4/s1600/error_culling.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="253" src="http://2.bp.blogspot.com/-wt-0Xqy0VnM/TZBysRtoVDI/AAAAAAAAAY0/Yd3SUw3avM4/s320/error_culling.jpg" width="320" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;It may not be obvious from an image instead of a realtime demo so I will try and explain. The above implemented patch culling is processed on&lt;br /&gt;the raw sphere data. This is equilavent to removing back-facing patches (anything from the back of the sphere, relative to the camera, is removed), then rotating the sphere on the Y axis (in the image above&lt;br /&gt;the sphere is rotated by 130 degrees) and then rendering with the API culling all back-facing polygons. This order is obviously incorrect. &lt;br /&gt;&lt;br /&gt;The more correct sequence would be to rotate the sphere, remove all back-facing patches, then render remaining patches and allow the API to remove any back-facing polygons in the front-facing patches. Since rotation occurs in the render pipeline it isn't possible for us to rotate before we remove the back-facing patches. &lt;br /&gt;&lt;br /&gt;The solution is to multiply the camera look-at vector by the modelview matrix. This is equilavent to transforming the camera by the same values that will be applied to the sphere, resulting in the correct back-facing patches being removed, regardless of what rotation/translation/scaling is applied to the sphere.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="color: blue;"&gt;float &lt;/span&gt;l_fDotProduct =&amp;nbsp; DotProduct(m_vNormal, p_pCamera-&amp;gt;get_LookAt() * p_pGraphics-&amp;gt;get_Matrix(eModelView));&lt;br /&gt;&lt;span style="color: blue;"&gt;if &lt;/span&gt;(0.0f &amp;gt; l_fDotProduct)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;return&lt;/span&gt;;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;(Note: Since p_pCamera-&amp;gt;get_LookAt() * p_pGraphics-&amp;gt;get_Matrix(eModelView) will yield the same value for every patch, it would be better to calculate this once per frame for each planet that is being rendered. This value can then be used within the test on each patch in the planet.)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2766425237491213801-4521361089790290449?l=decadeengine.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://decadeengine.blogspot.com/feeds/4521361089790290449/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://decadeengine.blogspot.com/2011/03/remove-back-facing-patches-before.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2766425237491213801/posts/default/4521361089790290449'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2766425237491213801/posts/default/4521361089790290449'/><link rel='alternate' type='text/html' href='http://decadeengine.blogspot.com/2011/03/remove-back-facing-patches-before.html' title='Remove back facing patches before the render pipeline.'/><author><name>Ciarán McCormack</name><uri>http://www.blogger.com/profile/12300242420318331807</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://4.bp.blogspot.com/-78XSmOD5nDE/TZBwzrTJVPI/AAAAAAAAAYw/BiNNwg8Hm4M/s72-c/PlanetPatch_withnormal.jpg' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2766425237491213801.post-7837304759927491444</id><published>2011-03-22T08:56:00.002Z</published><updated>2011-03-22T10:30:56.185Z</updated><title type='text'>Two steps forward, three steps back</title><content type='html'>In order to not admit what was probably a result of my own stupidity, I'm going to blame SVN. Regardless of what happened, it has now become apparent to me that the version of Decade Engine Source that I have isn't the latest version. It is missing my implementation of GPU planet generation. I've checked my online repository, backup disks etc .....&lt;br /&gt;&lt;br /&gt;This means that I have to recode those sections. A chore, but on a positive side, I know the pit-falls and issues I encountered the last time, and can hopefully design around these and end up with better solution.&lt;br /&gt;&lt;br /&gt;As per my previous post, I have also started IPhone and Android development. I shall be working on multiple projects at the same time, and rather than mix it all up on this blog, I have created a sister blog to this for &lt;a href="http://decadeenginemobile.blogspot.com/"&gt;Decade Mobile.&lt;/a&gt; Any updates which are specific to the mobile platforms shall be posted there.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2766425237491213801-7837304759927491444?l=decadeengine.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://decadeengine.blogspot.com/feeds/7837304759927491444/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://decadeengine.blogspot.com/2011/03/two-steps-forward-three-steps-back.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2766425237491213801/posts/default/7837304759927491444'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2766425237491213801/posts/default/7837304759927491444'/><link rel='alternate' type='text/html' href='http://decadeengine.blogspot.com/2011/03/two-steps-forward-three-steps-back.html' title='Two steps forward, three steps back'/><author><name>Ciarán McCormack</name><uri>http://www.blogger.com/profile/12300242420318331807</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2766425237491213801.post-2378012206085504075</id><published>2011-03-08T10:34:00.000Z</published><updated>2011-03-08T10:34:21.596Z</updated><title type='text'>Back online in Sydney</title><content type='html'>Hello again. Its been far to long! I am now settled and living in Sydney and have decided that the time to resume Decade is far overdue.&lt;br /&gt;&lt;br /&gt;Development of Decade shall continue as before with procedural planery bodies, but over the past few months I have started to program IPhone/IPad and Android, therefore I think it would be fun to create a mobile Decade Engine and try to make some simple but fun phone games.&lt;br /&gt;&lt;br /&gt;Let the adventure begin (yet again!)&lt;br /&gt;Ciarán&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2766425237491213801-2378012206085504075?l=decadeengine.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://decadeengine.blogspot.com/feeds/2378012206085504075/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://decadeengine.blogspot.com/2011/03/back-online-in-sydney.html#comment-form' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2766425237491213801/posts/default/2378012206085504075'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2766425237491213801/posts/default/2378012206085504075'/><link rel='alternate' type='text/html' href='http://decadeengine.blogspot.com/2011/03/back-online-in-sydney.html' title='Back online in Sydney'/><author><name>Ciarán McCormack</name><uri>http://www.blogger.com/profile/12300242420318331807</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2766425237491213801.post-1564112050644795511</id><published>2010-06-26T15:29:00.000+01:00</published><updated>2010-07-20T15:30:33.905+01:00</updated><title type='text'>Moving to Australia</title><content type='html'>Decade Engine will be on hold for a short while as I immigrate to  Australia. Thank you to everyone who has emailed questions and support  regarding my blog and development. I shall be back online and back in  development 'DownUnder'.&lt;br /&gt;&lt;br /&gt;Ciarán&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2766425237491213801-1564112050644795511?l=decadeengine.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://decadeengine.blogspot.com/feeds/1564112050644795511/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://decadeengine.blogspot.com/2010/06/moving-to-australia.html#comment-form' title='4 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2766425237491213801/posts/default/1564112050644795511'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2766425237491213801/posts/default/1564112050644795511'/><link rel='alternate' type='text/html' href='http://decadeengine.blogspot.com/2010/06/moving-to-australia.html' title='Moving to Australia'/><author><name>Ciarán McCormack</name><uri>http://www.blogger.com/profile/12300242420318331807</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2766425237491213801.post-8183108637090906594</id><published>2010-03-16T22:31:00.004Z</published><updated>2010-03-17T10:05:31.560Z</updated><title type='text'>GPU Procedural Planet</title><content type='html'>This example does not use any textures to colour the terrain, and is therefore 100% procedurally generated. In basic terms it means that no media is loaded. Everything is 100% generated in the engine.&lt;br /&gt;&lt;br /&gt;Let’s take some time to recap what needs to be procedurally generated in  order to render the planet (shown in the video below).&lt;br /&gt;&lt;br /&gt;&lt;i&gt;Permutations Texture&lt;/i&gt;&lt;br /&gt;The topography of the planet is created using noise algorithms. This  example uses Multi Ridged Brownian Fractal Motion.&amp;nbsp; At runtime this  noise is created using a series of permutations which are stored in a  texture so that it can be accessed by in a shader. The texture data  doesn’t make allot of visual sense, however here is an example of what  it looks like.&lt;br /&gt;&lt;div style="text-align: center;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://2.bp.blogspot.com/_awzb2-vllx8/S6AGDP37rmI/AAAAAAAAAYE/xHnu0_H6AnI/s1600-h/Permut.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://2.bp.blogspot.com/_awzb2-vllx8/S6AGDP37rmI/AAAAAAAAAYE/xHnu0_H6AnI/s320/Permut.jpg" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;i&gt;1 Vertex buffer&lt;/i&gt;&lt;br /&gt;The planet is rendered as a series of patches. It is this patch nature which allows the recursive sub-division resulting in the increased/decreased level of visible detail. Whereas the CPU Planet generates a unique vertex buffer for each patch (because the noise is calculated when the patch is created and applied to height data in the vertex buffer), the GPU Planet only uses 1 vertex buffer of X * X vertices, generated procedurally, which are displaced in a shader at runtime for each patch to be rendered.&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://4.bp.blogspot.com/_awzb2-vllx8/S6AGNn1LOJI/AAAAAAAAAYM/lL0HMr6araI/s1600-h/VertexBuffer.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://4.bp.blogspot.com/_awzb2-vllx8/S6AGNn1LOJI/AAAAAAAAAYM/lL0HMr6araI/s320/VertexBuffer.jpg" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;i&gt;16 Index Buffers&lt;/i&gt;&lt;br /&gt;An index buffer is used along with a vertex buffer to render some geometry. In allot of cases 1 vertex buffer is used with 1 index buffer. As described in previous posts a terrain requires 16 index buffers, generated procedurally, so that there are no terrain cracks. It must be possible for the edges of terrain patches, with different levels of detail, to join together seamlessly.&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://3.bp.blogspot.com/_awzb2-vllx8/S6AGqK5YjKI/AAAAAAAAAYU/LhwYIt4Oobs/s1600-h/IndexBuffer2.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://3.bp.blogspot.com/_awzb2-vllx8/S6AGqK5YjKI/AAAAAAAAAYU/LhwYIt4Oobs/s320/IndexBuffer2.jpg" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;div style="text-align: center;"&gt;&lt;object height="385" width="480"&gt;&lt;param name="movie" value="http://www.youtube.com/v/AmgAr5oyzAI&amp;amp;hl=en_GB&amp;amp;fs=1&amp;amp;"&gt;&lt;/param&gt;&lt;param name="allowFullScreen" value="true"&gt;&lt;/param&gt;&lt;param name="allowscriptaccess" value="always"&gt;&lt;/param&gt;&lt;embed src="http://www.youtube.com/v/AmgAr5oyzAI&amp;amp;hl=en_GB&amp;amp;fs=1&amp;amp;" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="480" height="385"&gt;&lt;/embed&gt;&lt;/object&gt;&lt;/div&gt;&lt;br /&gt;In the video above shows a basic GPU Planet. There is quiet an obvious bug visible as the camera moves. Because all noise is generated on the GPU, the Decade Engine running on the CPU has no knowledge of how much a vertex is displaced. All distance checking from the camera to the planet is calculated from the camera position to the underlying sphere of the planet (vertex displaced to radius of the planet but not with height noise applied). This is ok when the camera is high above the terrain however as the camera moves close to the surface, especially if this ground is at a high altitude, the sphere position may still be some distance beneath and therefore terrain subdivision do not occur properly.&lt;br /&gt;&lt;br /&gt;I am considering 2 possible techniques to over come this&lt;br /&gt;&lt;ol&gt;&lt;li&gt;Generate the same noise values on the CPU as is generated on the GPU. Since all (pseudo) random data is stored in the permutations texture, it should be possible.&lt;/li&gt;&lt;li&gt;Render the height data to a texture instead of generating it as required each frame, then use this texture for shader vertex displacement as well as calculating the height of key vertices on the CPU.&lt;/li&gt;&lt;/ol&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2766425237491213801-8183108637090906594?l=decadeengine.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://decadeengine.blogspot.com/feeds/8183108637090906594/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://decadeengine.blogspot.com/2010/03/gpu-procedural-planet.html#comment-form' title='5 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2766425237491213801/posts/default/8183108637090906594'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2766425237491213801/posts/default/8183108637090906594'/><link rel='alternate' type='text/html' href='http://decadeengine.blogspot.com/2010/03/gpu-procedural-planet.html' title='GPU Procedural Planet'/><author><name>Ciarán McCormack</name><uri>http://www.blogger.com/profile/12300242420318331807</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://2.bp.blogspot.com/_awzb2-vllx8/S6AGDP37rmI/AAAAAAAAAYE/xHnu0_H6AnI/s72-c/Permut.jpg' height='72' width='72'/><thr:total>5</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2766425237491213801.post-4996162226167564139</id><published>2010-02-24T22:48:00.004Z</published><updated>2010-02-26T13:30:09.063Z</updated><title type='text'>Concentric LOD Areas</title><content type='html'>Not really any new functionality, however small but important modifications. In the previous posts and video of the planet each patch was independent and updated when it thought correct regardless of the state of its neighbours. This resulted in a non-uniform patch pattern and multiple terrain cracks. A more detailed explanation of terrain cracks can be seen &lt;a href="http://decadeengine.blogspot.com/2008/03/terrain-cracks-revisited.html"&gt;here.&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://1.bp.blogspot.com/_awzb2-vllx8/S4Wj2HLlkSI/AAAAAAAAAXc/YmLQz3i4NZ4/s1600-h/Planet_LOD.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://1.bp.blogspot.com/_awzb2-vllx8/S4Wj2HLlkSI/AAAAAAAAAXc/YmLQz3i4NZ4/s320/Planet_LOD.jpg" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;Instead of a patchwork quilt on the planet surface, the terrain LOD (Level of Detail) decreases in concentric circles with its origin at the camera. All patches which neighbour a patch with lower LOD render the corner edge downgraded to the lower LOD preventing any terrain cracks appearing.&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://4.bp.blogspot.com/_awzb2-vllx8/S4WkJV27qcI/AAAAAAAAAXk/bu7NhPxEr4c/s1600-h/Planet_LOD2.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://4.bp.blogspot.com/_awzb2-vllx8/S4WkJV27qcI/AAAAAAAAAXk/bu7NhPxEr4c/s320/Planet_LOD2.jpg" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;In the above pictures the radius of the LOD circle is set to 6.0. This means that the LOD circle has a radius of the length of the patch at this level of detail multiplied by 6.0. This value can be changed at runtime if desired resulting in a higher or lower detail of terrain.&lt;br /&gt;&lt;br /&gt;Another change in the example, although not obvious from the pictures is that the planet is no longer updated/rendered from the root node. Now, during the first frame the lead patch is found. This is the patch that is directly below the camera at the correct LOD. Each frame when the planet updates the lead patch moves to one of its neighbours, children or its parent if required. This requires a little more code than simply recursively moving across the patch tree each frame, but should be faster as it removes the processing on many invisible patches (those which are closer to the root of the patch tree but are too low level of detail to meet our needs).&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2766425237491213801-4996162226167564139?l=decadeengine.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://decadeengine.blogspot.com/feeds/4996162226167564139/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://decadeengine.blogspot.com/2010/02/concentric-lod-areas.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2766425237491213801/posts/default/4996162226167564139'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2766425237491213801/posts/default/4996162226167564139'/><link rel='alternate' type='text/html' href='http://decadeengine.blogspot.com/2010/02/concentric-lod-areas.html' title='Concentric LOD Areas'/><author><name>Ciarán McCormack</name><uri>http://www.blogger.com/profile/12300242420318331807</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://1.bp.blogspot.com/_awzb2-vllx8/S4Wj2HLlkSI/AAAAAAAAAXc/YmLQz3i4NZ4/s72-c/Planet_LOD.jpg' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2766425237491213801.post-7014627852178200468</id><published>2010-01-15T18:08:00.068Z</published><updated>2010-01-20T09:12:19.597Z</updated><title type='text'>Procedural Planet - Subdividing Cube</title><content type='html'>At long last I have returned to what was the growing focus of Decade Engine in the latter stages of 2008. A &lt;a href="http://decadeengine.blogspot.com/2008/06/procedural-planet-texture-generation.html"&gt;previous post&lt;/a&gt; showed the most basic functionality of Decade's planet generation. I hope to give more details here.&lt;br /&gt;&lt;br /&gt;The below video has 3 sections.&lt;br /&gt;&lt;ol&gt;&lt;li&gt; Run-time cube subdivision and application of noise to create planet structure. Patch size is 10x10 quads. To give decent minimum resolution, the lowest possible level of subdividing in this example is 3, with the highest being 16. As the camera moves towards a patch, and gets within range (configured to radius of patch * 5 in this example) the patch subdivides into 4 children which are rendered instead of the parent when the camera is within range.&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Similar to section 1, except when the camera moves away from the patch, the level of detail which is rendered does not reduce. This would allow users to see the size of patches at every allowed level on screen at once, however when far away the patches at level 15 and/or 16 are smaller than 1 pixel so not really visible. Some very basic math will tell us that if the planet in view was earth size (i.e. radius of 6378km) the length of a patch at level 1 would be 7364.67km. At level 16 the patch length is only 0.1123km and with 10 quads per patch length, the max resolution of the planet is just above 1m. By increasing the max allowed depth rendered, or the resolution of each patch, this maximum planet resoultion could be increased to cm level.&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Using frustum culling is not enough to remove any unrendered polygons from the planet. When close to a planet it can look like a flat terrain, just like the earth does for us as we stand on it, but from height it can be seen that the planet is in-fact spherical. With this knowledge it is possible to mathematically remove allot of the planet patches which are on the opposite side of the planet. With Back face culling the API would remove these anyway, however it would be very wasteful to pass these invisible faces down the render pipeline. By using a DotProduct with the LookAt vector of the camera and the Normal of the planet patch translated to model space, it is very simple to ignore these patches.&lt;/li&gt;&lt;/ol&gt;&lt;br /&gt;&lt;center&gt;&lt;object height="344" width="425"&gt;&lt;param name="movie" value="http://www.youtube.com/v/cLydPHPWBO4&amp;amp;hl=en_GB&amp;amp;fs=1&amp;amp;"&gt;&lt;/param&gt;&lt;param name="allowFullScreen" value="true"&gt;&lt;/param&gt;&lt;param name="allowscriptaccess" value="always"&gt;&lt;/param&gt;&lt;embed src="http://www.youtube.com/v/cLydPHPWBO4&amp;amp;hl=en_GB&amp;amp;fs=1&amp;amp;" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="425" height="344"&gt;&lt;/embed&gt;&lt;/object&gt;&lt;/center&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2766425237491213801-7014627852178200468?l=decadeengine.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://decadeengine.blogspot.com/feeds/7014627852178200468/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://decadeengine.blogspot.com/2010/01/procedural-planet-subdividing-cube.html#comment-form' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2766425237491213801/posts/default/7014627852178200468'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2766425237491213801/posts/default/7014627852178200468'/><link rel='alternate' type='text/html' href='http://decadeengine.blogspot.com/2010/01/procedural-planet-subdividing-cube.html' title='Procedural Planet - Subdividing Cube'/><author><name>Ciarán McCormack</name><uri>http://www.blogger.com/profile/12300242420318331807</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2766425237491213801.post-8634306128487551599</id><published>2009-12-09T20:26:00.003Z</published><updated>2009-12-09T20:28:31.936Z</updated><title type='text'>Terrain Editor - Version 2</title><content type='html'>&lt;div style="text-align: left;"&gt;Last week I received a request from a reader of DecadeBlog for access to the terrain editor. What little pride I have kicked in and in an effort to supply something a little more usable than Version 1 I set aside a little bit of time to add some features.&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;Version 2 is representitive of a more traditional editor, showing multiple views of the subject. 3 independent views of the terrain can be seen in the video below. Each view maintains its own render state. It is, for example, possible to show one view in wireframe, while the others remain solid or are shown in point form. There is also correct "Screen to World Projection" for each view.&lt;br /&gt;&lt;br /&gt;Version 2 also contains some erosion filters. I noticed when editing that the old issue of &lt;a href="http://decadeengine.blogspot.com/2007/04/bitter-sweet-success.html"&gt;terrain steps&lt;/a&gt; was occuring. By giving the ability to erode or filter the terrain any rough edges are smoothed out.&lt;br /&gt;&lt;br /&gt;&lt;div style="text-align: center;"&gt;&lt;object height="344" width="425"&gt;&lt;param name="movie" value="http://www.youtube.com/v/J_lIMaYI0gw&amp;amp;hl=en_GB&amp;amp;fs=1&amp;amp;"&gt;&lt;/param&gt;&lt;param name="allowFullScreen" value="true"&gt;&lt;/param&gt;&lt;param name="allowscriptaccess" value="always"&gt;&lt;/param&gt;&lt;embed src="http://www.youtube.com/v/J_lIMaYI0gw&amp;amp;hl=en_GB&amp;amp;fs=1&amp;amp;" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="425" height="344"&gt;&lt;/embed&gt;&lt;/object&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;All application level in the above example is again scripted. On startup the DecadeEngine Sandbox calls the script init function and each frame the HandleInput, Update, Render3d and Render2d functions are called in the script. If anyone is interested in having the script please &lt;a href="mailto:decadeengine@ymail.com"&gt;mail me&lt;/a&gt; or comment to this post. Its a little long and boring to publish here.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2766425237491213801-8634306128487551599?l=decadeengine.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://decadeengine.blogspot.com/feeds/8634306128487551599/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://decadeengine.blogspot.com/2009/12/terrain-editor-version-2.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2766425237491213801/posts/default/8634306128487551599'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2766425237491213801/posts/default/8634306128487551599'/><link rel='alternate' type='text/html' href='http://decadeengine.blogspot.com/2009/12/terrain-editor-version-2.html' title='Terrain Editor - Version 2'/><author><name>Ciarán McCormack</name><uri>http://www.blogger.com/profile/12300242420318331807</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2766425237491213801.post-1951971491801000036</id><published>2009-11-25T19:39:00.006Z</published><updated>2009-11-25T20:02:16.654Z</updated><title type='text'>CPU v GPU Procedural Terrain Texture Generation</title><content type='html'>Its been an interesting week. Having programmed graphics for some time, having read allot about &lt;span id="misspell-0"&gt;shaders&lt;/span&gt; and having used them briefly I know they are powerful tools for the graphics programmer, but I am still slightly in awe of how quick they are.&lt;br /&gt;&lt;br /&gt;It should be noted before reading any further that this is the first &lt;span id="misspell-1"&gt;shader&lt;/span&gt; I have ever written. I've used and modified &lt;span id="misspell-2"&gt;shaders&lt;/span&gt; before such as Sean &lt;span id="misspell-3"&gt;O'Neil's&lt;/span&gt; atmospheric scattering (there is a post below somewhere) and some &lt;span id="misspell-4"&gt;bumpmapping&lt;/span&gt;, but all code in this &lt;span id="misspell-5"&gt;shader&lt;/span&gt; is mine and therefore possibly with some rookie mistakes.&lt;br /&gt;&lt;br /&gt;Lets first refresh on the very simple texture generation technique currently implemented. The user specifies a list of terrain regions. Each region has texture data, an optimal, min and max height associated with it. For each pixel in the texture being generated the terrain height at that position is queried, interpolated if required (if the texture is higher resolution than the terrain mesh). This height is then compared to all terrain regions and a &lt;span id="misspell-6"&gt;colour&lt;/span&gt; of the pixel is based on the strength of this height within the regions. There are many examples of the results of this algorithm elsewhere in the blog if you have not already seen.&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://3.bp.blogspot.com/_awzb2-vllx8/Sw1_tq0hv7I/AAAAAAAAAXM/3II5OVL6QkY/s1600/graph_CPU.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://3.bp.blogspot.com/_awzb2-vllx8/Sw1_tq0hv7I/AAAAAAAAAXM/3II5OVL6QkY/s320/graph_CPU.jpg" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;Above can be seen the times used to generate the textures in software. 2048x2048 taking almost 1 minute! My code in this area isn't by any means heavily optimised, but is well written. Its a relatively simple algorithm of iterating though a list and comparing the height value against the region. Previously when procedurally generating a planet at run-time the texture size of choice was 256x256. This provided average detail but with the generation time of about 1 second, a freeze in movement was very obvious.&lt;br /&gt;&lt;br /&gt;Now on to the better news....&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://4.bp.blogspot.com/_awzb2-vllx8/Sw2Cj6tJ9lI/AAAAAAAAAXU/Iym1AvGyShE/s1600/graph_GPU.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://4.bp.blogspot.com/_awzb2-vllx8/Sw2Cj6tJ9lI/AAAAAAAAAXU/Iym1AvGyShE/s320/graph_GPU.jpg" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;What a difference? These times include the full process of using a the shader&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Binding the Frame buffer so that the texture can be rendered off screen,&lt;/li&gt;&lt;li&gt;Enabling the Vertex and Fragment &lt;span id="misspell-7"&gt;shader&lt;/span&gt;, binding the textures required.&lt;/li&gt;&lt;li&gt;Rendering the texture&lt;/li&gt;&lt;li&gt;Unbinding/disabling everything used during this sequence.&amp;nbsp;&lt;/li&gt;&lt;/ul&gt;To get a better approximation on the time used to generate this texture in hardware the times above are also an average of 5000 iterations (that applies only to the &lt;span id="misspell-8"&gt;GPU&lt;/span&gt; times as it would take over 3 days waiting for 5000 2048x2048 CPU textures to be generated).&lt;br /&gt;Here is the fragment shader, which does all the work. The vertex shader just passes the vertex down the render pipeline.&lt;br /&gt;&lt;br /&gt;&lt;span style="color: blue;"&gt;struct&lt;/span&gt; vOutput &lt;br /&gt;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="background-color: white; color: blue;"&gt;float4&lt;/span&gt; color : &lt;span style="color: blue;"&gt;COLOR&lt;/span&gt;;&lt;br /&gt;};&lt;br /&gt;&lt;br /&gt;&lt;span style="color: blue;"&gt;struct&lt;/span&gt; TextureRegion&lt;br /&gt;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;float2&lt;/span&gt; startTextureCoord;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;float2&lt;/span&gt; endTextureCoord;&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;float&lt;/span&gt; optimalHeight;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&lt;span style="background-color: white;"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="background-color: blue;"&gt;&lt;span style="background-color: white;"&gt; &lt;span style="color: blue;"&gt;float&lt;/span&gt;&lt;/span&gt;&lt;/span&gt; minHeight;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;float&lt;/span&gt; maxHeight;&lt;br /&gt;};&lt;br /&gt;&lt;br /&gt;vOutput Main(&lt;span style="color: blue;"&gt;float2&lt;/span&gt; texCoord : &lt;span style="color: blue;"&gt;TEXCOORD0&lt;/span&gt;, &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;&amp;nbsp;uniform sampler2D&lt;/span&gt; heightMap : &lt;span style="color: blue;"&gt;TEX0&lt;/span&gt;, &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&lt;span style="background-color: white; color: blue;"&gt;uniform sampler2D&lt;/span&gt; terrainTexture : &lt;span style="color: blue;"&gt;TEX1&lt;/span&gt;,&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&lt;span style="color: blue;"&gt;uniform int&lt;/span&gt; terrainTextureRepeat,&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&lt;span style="color: blue;"&gt;uniform sampler2D&lt;/span&gt; detailTexture : &lt;span style="color: blue;"&gt;TEX2&lt;/span&gt;,&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;&amp;nbsp;uniform int&lt;/span&gt; detailTextureRepeat,&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&lt;span style="color: blue;"&gt;uniform float&lt;/span&gt; blendingRatio,&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&lt;span style="color: blue;"&gt;uniform&lt;/span&gt; TextureRegion regions[4])&lt;br /&gt;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; vOutput OUT;&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: #38761d;"&gt; //Get the Height&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: blue;"&gt; float4&lt;/span&gt; bytes = &lt;span style="color: blue;"&gt;tex2D&lt;/span&gt;(heightMap, texCoord);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: blue;"&gt; float&lt;/span&gt; height = ((bytes[0] * 16777216.0f) + (bytes[1] * 65536.0f) + (bytes[2] * 256.0f)) / 1000.0f;&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: #38761d;"&gt;//Strength of this Terrain Tile at this height&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: blue;"&gt; float&lt;/span&gt; strength = 0.0f;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: #38761d;"&gt; //Color for this Pixel&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; OUT.color = &lt;span style="color: blue;"&gt;float4&lt;/span&gt;(0, 0, 0, 1);&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;int&lt;/span&gt; colorset = 0;&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: #38761d;"&gt; //For Each Terrain Tile Defined&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;for&lt;/span&gt; (&lt;span style="color: blue;"&gt;int&lt;/span&gt; loop = 0; loop &amp;lt; 4; loop++)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: #38761d;"&gt; //If the Current Terrain Pixel Falls within this range&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;if&lt;/span&gt; (height &amp;gt; regions[loop].minHeight &amp;amp;&amp;amp; regions[loop].maxHeight &amp;gt; height)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; colorset = 1;&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: #38761d;"&gt;//Work out the % that applies to this height&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #38761d;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; //If Height = Optimal, then its 100% otherwise fade out relative to distance between optimal and min/max&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;if&lt;/span&gt; (height == regions[loop].optimalHeight)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; strength = 1.0f;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;else if&lt;/span&gt; (height &amp;gt; regions[loop].optimalHeight)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;float&lt;/span&gt; temp1 = regions[loop].maxHeight - regions[loop].optimalHeight;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; strength = ((temp1 - (height - regions[loop].optimalHeight)) / temp1);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;else if&lt;/span&gt; (height &amp;lt; regions[loop].optimalHeight)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;float&lt;/span&gt; temp1 = height - regions[loop].minHeight;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: blue;"&gt; float&lt;/span&gt; temp2 = regions[loop].optimalHeight - regions[loop].minHeight;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; strength = temp1 / temp2;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;if&lt;/span&gt; (strength != 0.0f)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;float2&lt;/span&gt; tileTexCoord;&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: #38761d;"&gt;//Tile the Texture Coordinates&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; tileTexCoord[0] =&lt;span style="color: blue;"&gt; fmod&lt;/span&gt;((texCoord[0] * terrainTextureRepeat), 1.0f);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; tileTexCoord[1] = &lt;span style="color: blue;"&gt;fmod&lt;/span&gt;((texCoord[1] * terrainTextureRepeat), 1.0f);&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: #38761d;"&gt;//Recalculate the Texture Coordinates so that they are within the Specified Tile&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; tileTexCoord = regions[loop].startTextureCoord + ((regions[loop].endTextureCoord - regions[loop].startTextureCoord) * tileTexCoord);&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: #38761d;"&gt;//Get the Color at this Terrain Coordinate&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; OUT.color += (&lt;span style="color: blue;"&gt;tex2D&lt;/span&gt;(terrainTexture, tileTexCoord) * strength);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;if&lt;/span&gt; (0.0f == colorset)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: #38761d;"&gt;//Make Pink so that its obvious on the terrain (only for debugging)&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; OUT.color = &lt;span style="color: blue;"&gt;float4&lt;/span&gt;(1, 0, 1, 1);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;else&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: #38761d;"&gt;//Scale the Texture Coordinate for Repeating detail and get the Detail Map Color&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; texCoord *= detailTextureRepeat;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; float4 detailColor = &lt;span style="color: blue;"&gt;tex2D&lt;/span&gt;(detailTexture, texCoord);&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: #38761d;"&gt;//Interpolate Between the 2 Colors to get final Color&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; OUT.color =&lt;span style="color: blue;"&gt; lerp&lt;/span&gt;(OUT.color, detailColor, blendingRatio);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: blue;"&gt; return&lt;/span&gt; OUT;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;This week I have been using this shader in 2 ways.&lt;br /&gt;&lt;br /&gt;&lt;ol&gt;&lt;li&gt;Use as described above, to generate a texture once per terrain patch (will get generated in higher detail when the patch subdivides) and this texture is then used when rendering.&lt;/li&gt;&lt;li&gt;Use and bind every frame which gives per-pixel texture generation. This has the obvious disadvantage of requiring that the texture data for the terrain is generated each frame, but obviously does so for only the onscreen terrain. It has the nice advantage of not taking up any graphics memory, no need for frame buffers, rendering off screen, etc.... I was getting between 200 and 600 fps using this method.&lt;/li&gt;&lt;/ol&gt;I dont know how I will ultimately use this shader in the future. I will have to experiment and see which is the preferred method.&lt;br /&gt;&lt;br /&gt;All the above results were generated on my laptop which has the following.&lt;br /&gt;&lt;br /&gt;Renderer: ATI Mobility Radeon HD 3670&lt;br /&gt;Vendor: ATI Technologies Inc.&lt;br /&gt;Memory: 512 MB&lt;br /&gt;Version: 3.0.8599 Forward-Compatible Context&lt;br /&gt;Shading language version: 1.30&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Max texture size: 8192 x 8192&lt;br /&gt;Max texture coordinates: 16&lt;br /&gt;Max vertex texture image units: 16&lt;br /&gt;Max texture image units: 16&lt;br /&gt;Max geometry texture units: 0&lt;br /&gt;Max anisotropic filtering value: 16&lt;br /&gt;Max number of light sources: 8&lt;br /&gt;Max viewport size: 8192 x 8192&lt;br /&gt;Max uniform vertex components: 512&lt;br /&gt;Max uniform fragment components: 512&lt;br /&gt;Max geometry uniform components: 0&lt;br /&gt;Max varying floats: 68&lt;br /&gt;Max samples: 8&lt;br /&gt;Max draw buffers: 8&lt;br /&gt;&lt;br /&gt;As always comments are welcome and appreciated.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2766425237491213801-1951971491801000036?l=decadeengine.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://decadeengine.blogspot.com/feeds/1951971491801000036/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://decadeengine.blogspot.com/2009/11/cpu-v-gpu-procedural-terrain-texture.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2766425237491213801/posts/default/1951971491801000036'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2766425237491213801/posts/default/1951971491801000036'/><link rel='alternate' type='text/html' href='http://decadeengine.blogspot.com/2009/11/cpu-v-gpu-procedural-terrain-texture.html' title='CPU v GPU Procedural Terrain Texture Generation'/><author><name>Ciarán McCormack</name><uri>http://www.blogger.com/profile/12300242420318331807</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://3.bp.blogspot.com/_awzb2-vllx8/Sw1_tq0hv7I/AAAAAAAAAXM/3II5OVL6QkY/s72-c/graph_CPU.jpg' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2766425237491213801.post-2614607304501732747</id><published>2009-11-19T09:26:00.003Z</published><updated>2009-11-19T09:57:00.324Z</updated><title type='text'>Higher Detail Heightmap Textures</title><content type='html'>When originally creating height maps, most of the tutorials store this information in grey-scale, therefore at the time this is what was implemented in decade. Limited to 256 different heights (as only 1 byte is used per value) it may be acceptable for demo's with small terrain patches, but is inadequate for anything larger with a more realistic topography.&lt;br /&gt;&lt;br /&gt;To overcome this a terrain file format was created for decade. This allowed the saving of height data to a binary or text file using multiple bytes per value. With the introduction of shaders into Decade terrain engine, this too has become inadequate. I need to send the height information to the shader, along with the source tiles so that the procedural terrain texture can be created. The only feasible way to send this height information to the Graphics Card is in a texture, but the grey-scale implementation did not have high enough detail.&lt;br /&gt;&lt;br /&gt;Solution? Combine the texture implementation with the multi-byte file format. To do this I split the floating point height position across the 3 color bytes using some simple bit shifting.&lt;br /&gt;&lt;br /&gt;Using 3 bytes it is possible to represent 16777216 unique values (256x256x256). In the following example I want to maintain 3 digits after the decimal separator. This allows me to have terrain heights from 0.000 to 16777.216 which should be suitable for most procedural planets. It is of course possible to make the number of decimal digits configurable.&lt;br /&gt;&lt;br /&gt;To convert a floating point height into 3 bytes (used in the texture rgb).&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;&lt;span style="font-style:italic;"&gt;&lt;br /&gt;//Get the Height at the current Terrain Position&lt;br /&gt;float l_fHeight = get_HeightAtPoint(l_iXPosition, l_iYPosition);&lt;br /&gt;&lt;br /&gt;//Convert to an int. Multiply by 1000 to keep 3 decmial places.&lt;br /&gt;int l_iColor = (int)(l_fHeight * 1000);&lt;br /&gt;&lt;br /&gt;//Seperate into 3 Bytes&lt;br /&gt;l_ucRed = ((l_iHeight &gt;&gt; 16) &amp;amp; 0xFFFF);&lt;br /&gt;l_ucGreen = ((l_iHeight &gt;&gt; 8) &amp;amp; 0xFF);&lt;br /&gt;l_ucBlue = l_iHeight &amp;amp; 0xFF;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;and to convert 3 bytes back into a float, with 3 decimal places is as easy as&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;&lt;span style="font-style:italic;"&gt;l_fHeight = ((l_ucRed &lt;&lt; 16) | (l_ucGreen &lt;&lt; 8) | l_ucBlue) / 1000.0f;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_awzb2-vllx8/SwUVoAr-omI/AAAAAAAAAXE/-lIhX9dtw9g/s1600/HeightMap.JPG"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 400px; height: 249px;" src="http://2.bp.blogspot.com/_awzb2-vllx8/SwUVoAr-omI/AAAAAAAAAXE/-lIhX9dtw9g/s400/HeightMap.JPG" border="0" alt=""id="BLOGGER_PHOTO_ID_5405750704851559010" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Above is a sample showing grey-scale height maps and their equivalent 24bit height maps. When I first saw the new maps, I thought there was a bug, and there would be rough edges in the terrain, due to the sudden color changes within the texture, however it loads correctly and terrain detail is maintained.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2766425237491213801-2614607304501732747?l=decadeengine.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://decadeengine.blogspot.com/feeds/2614607304501732747/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://decadeengine.blogspot.com/2009/11/higher-detail-heightmap-textures.html#comment-form' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2766425237491213801/posts/default/2614607304501732747'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2766425237491213801/posts/default/2614607304501732747'/><link rel='alternate' type='text/html' href='http://decadeengine.blogspot.com/2009/11/higher-detail-heightmap-textures.html' title='Higher Detail Heightmap Textures'/><author><name>Ciarán McCormack</name><uri>http://www.blogger.com/profile/12300242420318331807</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://2.bp.blogspot.com/_awzb2-vllx8/SwUVoAr-omI/AAAAAAAAAXE/-lIhX9dtw9g/s72-c/HeightMap.JPG' height='72' width='72'/><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2766425237491213801.post-3573446870346360054</id><published>2009-11-10T11:42:00.003Z</published><updated>2009-11-10T11:50:39.670Z</updated><title type='text'>Winter is returning and I'm back again.</title><content type='html'>Yet again the summer months have been a slack time for Decade. As a solo hobby project I find it very difficult to sit at my PC after a long day in the office when the sun is shining outside. Now that the cold, wet and dark nights are back I feel the urge to return to Decade and complete some of my long standing wishlist features.&lt;br /&gt;&lt;br /&gt;Over the past week or two I've been researching shaders. I have decided to add support for CG and CGFX to Decade. My first task with this will be to move the procedural texture generation to the GPU. This should hopefully vastly speed up this area of the engine allowing much smoother planet generation.&lt;br /&gt;&lt;br /&gt;Having reviewed the Decade code with a fresh mind, some housekeeping is first required. Cleaning up interfaces and improving segments before building upon. Within the next week I hope to have some comparisons between generating the textures on the CPU and the GPU. Not having much experience using the GPU for this type of processing I am unsure what to expect but from reading other blogs regarding Planet and Terrain generation I am confident that it is the right approach to take.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2766425237491213801-3573446870346360054?l=decadeengine.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://decadeengine.blogspot.com/feeds/3573446870346360054/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://decadeengine.blogspot.com/2009/11/winter-is-returning-and-im-back-again.html#comment-form' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2766425237491213801/posts/default/3573446870346360054'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2766425237491213801/posts/default/3573446870346360054'/><link rel='alternate' type='text/html' href='http://decadeengine.blogspot.com/2009/11/winter-is-returning-and-im-back-again.html' title='Winter is returning and I&apos;m back again.'/><author><name>Ciarán McCormack</name><uri>http://www.blogger.com/profile/12300242420318331807</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2766425237491213801.post-2280379849587391772</id><published>2009-02-23T07:44:00.002Z</published><updated>2009-02-23T12:07:47.996Z</updated><title type='text'>Basic Terrain Editor</title><content type='html'>This update in itself probably does not deserve a full blog update however its been too long since I have reported any Engine Progress and some nice features have been added.&lt;br /&gt;&lt;br /&gt;The video below shows my sandbox terrain editor. This is running in Engine Real time. By changing the size of the target area and using the mouse wheel it is possible to raise or lower segments of terrain. As the terrain changes the terrain texture is recalculated (for modified areas).&lt;br /&gt;&lt;br /&gt;&lt;center&gt;&lt;object width="425" height="344"&gt;&lt;param name="movie" value="http://www.youtube.com/v/omMn224M0Xs&amp;hl=en&amp;fs=1"&gt;&lt;/param&gt;&lt;param name="allowFullScreen" value="true"&gt;&lt;/param&gt;&lt;param name="allowscriptaccess" value="always"&gt;&lt;/param&gt;&lt;embed src="http://www.youtube.com/v/omMn224M0Xs&amp;hl=en&amp;fs=1" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="425" height="344"&gt;&lt;/embed&gt;&lt;/object&gt;&lt;/center&gt;&lt;br /&gt;&lt;br /&gt;Key features:&lt;ul&gt;&lt;li&gt;Dynamic Vertex Buffer Object updating when terrain is updated&lt;/li&gt;&lt;li&gt;Dynamic Texture Updating when terrain is updated (from a set of source textures and height values (Optimal, Min, Max)&lt;/li&gt;&lt;li&gt;Screen to World projection allowing Decade to know where in the world the user is selecting with the mouse.&lt;/li&gt;&lt;li&gt;High level functionality of demo is 100% scripted (which calls Engine functions bound to script engine)&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_awzb2-vllx8/SaKMRwH8bJI/AAAAAAAAAWI/JteQBnoLIb0/s1600-h/script.JPG"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 220px; height: 400px;" src="http://4.bp.blogspot.com/_awzb2-vllx8/SaKMRwH8bJI/AAAAAAAAAWI/JteQBnoLIb0/s400/script.JPG" border="0" alt=""id="BLOGGER_PHOTO_ID_5305957547599752338" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;A GUI system is also in development. This system is based on my experience of C#. It is possible to register events for each GUI component on the engine or script level. These events are fired under the specified circumstances. e.g. Mouse Enters, Mouse Leaves, MouseLeftClicked etc... &lt;br /&gt;&lt;br /&gt;Version 2 of the Terrain Editor should make use of this GUI system and also support features such as&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Adding areas of Water&lt;/li&gt;&lt;li&gt;Adding areas of vegetation&lt;/li&gt;&lt;li&gt;Erosion Filters on selected area or whole terrain&lt;/li&gt;&lt;li&gt;Texture splashing for better terrain details. (Roads, coast line etc...)&lt;/li&gt;&lt;/ul&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2766425237491213801-2280379849587391772?l=decadeengine.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://decadeengine.blogspot.com/feeds/2280379849587391772/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://decadeengine.blogspot.com/2009/02/basic-terrain-editor.html#comment-form' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2766425237491213801/posts/default/2280379849587391772'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2766425237491213801/posts/default/2280379849587391772'/><link rel='alternate' type='text/html' href='http://decadeengine.blogspot.com/2009/02/basic-terrain-editor.html' title='Basic Terrain Editor'/><author><name>Ciarán McCormack</name><uri>http://www.blogger.com/profile/12300242420318331807</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://4.bp.blogspot.com/_awzb2-vllx8/SaKMRwH8bJI/AAAAAAAAAWI/JteQBnoLIb0/s72-c/script.JPG' height='72' width='72'/><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2766425237491213801.post-244820396203620340</id><published>2008-10-29T22:13:00.000Z</published><updated>2008-10-30T13:20:46.370Z</updated><title type='text'>Would you like to use Decade?</title><content type='html'>Over the past few months I have received a number of requests from people wishing to use Decade in their personal probjects and also a possible commercial venture (with alot more work to be completed on Decade before this is possible). If you would like to use Decade in any of your project or have any questions which wouldnt suffice asking in the comments section of this blog then please email me at decadeengine@ymail.com&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2766425237491213801-244820396203620340?l=decadeengine.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://decadeengine.blogspot.com/feeds/244820396203620340/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://decadeengine.blogspot.com/2008/10/would-you-like-to-use-decade.html#comment-form' title='4 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2766425237491213801/posts/default/244820396203620340'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2766425237491213801/posts/default/244820396203620340'/><link rel='alternate' type='text/html' href='http://decadeengine.blogspot.com/2008/10/would-you-like-to-use-decade.html' title='Would you like to use Decade?'/><author><name>Ciarán McCormack</name><uri>http://www.blogger.com/profile/12300242420318331807</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2766425237491213801.post-6471163474793053963</id><published>2008-10-26T20:02:00.001Z</published><updated>2008-10-30T13:20:28.957Z</updated><title type='text'>Its been a long time</title><content type='html'>I truly cannot believe that it has been 4 months since I've updated this blog. The summer months have sped past. There was a period of quiet time for Decade with me taking time out for holidays and then some personal time to relax and pursue other projects. A number of weeks ago I approached Decade again and have since given it a complete overhaul.&lt;br /&gt;&lt;br /&gt;No longer is Decade contained within 1 project. Logically dividing the sections up into DecadeUtilities, DecadeScript, DecadePhysics, DecadeInput, DecadeOnline, DecadeGraphics and DecadeEngine, a DLL has been created for each resulting in a complete game engine. Another advantage of this is that each of the components resides behind an "Abstraction Layer" therefore allowing me to change individual components such as graphics API, physics engine without having to recompile and deliver the whole game.&lt;br /&gt;&lt;br /&gt;The names of the components descript pretty well what functionality is contained however for clarity I will give a brief overview starting at the bottom.&lt;br /&gt;DecadeUtilities contains random functionality which does not meet the criteria of the other DLL's as well as functionality which is common to many of the DLL's higher up the chain. e.g Math, I/O&lt;br /&gt;&lt;br /&gt;DecadeScript contains methods for loading and executing scripts at run time. As well as Decade calling functions within the script, most of the objects in the Decade suite of DLL's have been bound to the script engine allowing powerful control of the game engine from the script level. In the long term this will allow allot of customisation and add on capability to games made with the Decade Engine. Supported script engines are &lt;a href="http://www.somedude.net/gamemonkey/"&gt;Game Monkey&lt;/a&gt; with &lt;a href="http://www.lua.org/"&gt;LUA&lt;/a&gt; support currently being added.&lt;br /&gt;&lt;br /&gt;DecadePhysics as the name suggests contains a physics engine. In keeping with the other DLL's in the Decade Suite all the physics engine functionality is contained within an "Abstraction Layer" which will allow support for other physics engines to be added quickly and easily. &lt;a href="http://www.ode.org/"&gt;ODE&lt;/a&gt; is the current 3rd party physics engine supported by Decade.&lt;br /&gt;&lt;br /&gt;DecadeInput contains functionality for all input methods. Keyboard, Mouse and Joystick/Joypad support are easy to add to your game project and with simple bindings to the script engine it takes a matter of minutes to map your keypress's or mouse moves to your desired functionality.&lt;br /&gt;&lt;br /&gt;DecadeOnline is the encapsulation of online communication methods for multi-player online games. Offering you the possibility to create a server or client with ease and communicate over TCP or UDP.&lt;br /&gt;&lt;br /&gt;DecadeGraphics contains all the graphics API functionality required in a 2D or 3D game, from creating an index or vertex buffer, loading a texture to graphics memory, executing a vertex or fragment shader. DecadeEngine currently uses OpenGL however a DirectX version of this DLL should be available in the near future.&lt;br /&gt;&lt;br /&gt;DecadeEngine is the main interface to the Decade suite. This layer contains all the 2D and 3D engine functionality such as loading a texture, loading a mesh, creating a terrain or planet, lights, shadows etc....&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2766425237491213801-6471163474793053963?l=decadeengine.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://decadeengine.blogspot.com/feeds/6471163474793053963/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://decadeengine.blogspot.com/2008/10/its-been-long-time.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2766425237491213801/posts/default/6471163474793053963'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2766425237491213801/posts/default/6471163474793053963'/><link rel='alternate' type='text/html' href='http://decadeengine.blogspot.com/2008/10/its-been-long-time.html' title='Its been a long time'/><author><name>Ciarán McCormack</name><uri>http://www.blogger.com/profile/12300242420318331807</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2766425237491213801.post-3854990877129199182</id><published>2008-06-16T21:49:00.002+01:00</published><updated>2008-06-16T22:12:37.384+01:00</updated><title type='text'>Procedural Planet - Texture Generation</title><content type='html'>Texture Generation for procedural planet was a simple step up from generating height based texture for a flat terrain. Because the underlying structure of each planet is a cube, 6 textures are required for each planet. The height is calculated from the distance of the vertex to the centre of the planet, minus the base radius of the planet. This method allows 100% re usage of the normal terrain height map and texture generation functionality.&lt;br /&gt;&lt;br /&gt;&lt;center&gt;&lt;br /&gt;&lt;object width="425" height="344"&gt;&lt;param name="movie" value="http://www.youtube.com/v/FRssl_S9q-g&amp;hl=en"&gt;&lt;/param&gt;&lt;embed src="http://www.youtube.com/v/FRssl_S9q-g&amp;hl=en" type="application/x-shockwave-flash" width="425" height="344"&gt;&lt;/embed&gt;&lt;/object&gt;&lt;br /&gt;&lt;/center&gt;&lt;br /&gt;&lt;br /&gt;In the above video the planet is made up of 125x125x6 vertices's and the moon from 65x65x6 faces. There is currently no complete LOD functionality. When fully implemented each face recursively subdivides into 4 faces of equal area, resulting in the level of detail of each face increasing by a level of 4 with each divide. &lt;br /&gt;&lt;br /&gt;With some clean programming, a vertex should never have to be calculated more than once (unless the player moves a distance away and the section is deleted from memory). The parent will populate each of its children with the relevant subset of its data, and only the unknown sections calculated, resulting in lower memory usage as well as faster run time higher LOD generation.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2766425237491213801-3854990877129199182?l=decadeengine.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://decadeengine.blogspot.com/feeds/3854990877129199182/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://decadeengine.blogspot.com/2008/06/procedural-planet-texture-generation.html#comment-form' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2766425237491213801/posts/default/3854990877129199182'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2766425237491213801/posts/default/3854990877129199182'/><link rel='alternate' type='text/html' href='http://decadeengine.blogspot.com/2008/06/procedural-planet-texture-generation.html' title='Procedural Planet - Texture Generation'/><author><name>Ciarán McCormack</name><uri>http://www.blogger.com/profile/12300242420318331807</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2766425237491213801.post-3528675679997442376</id><published>2008-05-23T19:17:00.001+01:00</published><updated>2008-05-29T19:36:46.537+01:00</updated><title type='text'>Procedural Planet</title><content type='html'>&lt;p&gt;In continuation to the &lt;a href="http://decadeengine.blogspot.com/2007/10/procedural-sphere.html"&gt;Procedural Sphere&lt;/a&gt; entry I made a few months ago, and from inspiration by the ongoing work of &lt;a href="http://jellyengine.blogspot.com/"&gt;Jelly Edwards&lt;/a&gt; I decided to look into further developing the sub-dividing cube with procedural noise in order to make a planet.&lt;br /&gt;&lt;br /&gt;The noise algorithm used is &lt;a href="http://en.wikipedia.org/wiki/Fractional_Brownian_motion"&gt;Fractional Brownian motion (fBm)&lt;/a&gt; which is a form of &lt;a href="http://mrl.nyu.edu/~perlin/"&gt;Perlin Noise&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;A good article about fBm in relation to procedural planets can be seen &lt;a href="http://www.gamasutra.com/features/20010302/oneil_01.htm"&gt;here&lt;/a&gt;. This work was carried out by &lt;a href="http://sponeil.net/index.htm"&gt;Sean O'Neill&lt;/a&gt; who has also contributed allot to atmospheric scattering.&lt;br /&gt;&lt;br /&gt;Very early and basic attempts at a procedural planet can be seen below. For the purpose of illustrating the deformation of the sphere I have magnified the hills and valleys on the planet, which results in what looks like an asteroid or moon.&lt;br /&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;a href="http://1.bp.blogspot.com/_awzb2-vllx8/SD7zfgBu-2I/AAAAAAAAAQA/SkRJIMVtszM/s1600-h/planet_19_05_2008.JPG"&gt;&lt;img id="BLOGGER_PHOTO_ID_5205865941785574242" style="DISPLAY: block; MARGIN: 0px auto 10px; CURSOR: hand; TEXT-ALIGN: center" alt="" src="http://1.bp.blogspot.com/_awzb2-vllx8/SD7zfgBu-2I/AAAAAAAAAQA/SkRJIMVtszM/s400/planet_19_05_2008.JPG" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;There are some key failings with this version. It is slow to render as the vertex and index buffers and built each frame. The whole planet is the same Level of Detail (LOD). This is ok for distance viewing, however as the camera approaches the surface of the planet, rendering the entire scene at a high LOD would cripple even the most powerful of computers.&lt;br /&gt;&lt;br /&gt;Many of the techniques learned when researching and implementing my terrain system will be used here. &lt;/p&gt;&lt;ul&gt;&lt;li&gt;Dividing the planet surface into patches&lt;/li&gt;&lt;li&gt;Each Patch manages their own LOD (through subdivision and creation of child patches) based on distance from the camera.&lt;/li&gt;&lt;li&gt;Each Patch maintains its own Vertex Buffer, while sharing a group of Index Buffers (to cover neighbour patches with different LOD's)&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;Allot of my terrain modules can be reused, with perhaps a little added functionality, so I hope that, time permitting, adding these features will not take too long.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2766425237491213801-3528675679997442376?l=decadeengine.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://decadeengine.blogspot.com/feeds/3528675679997442376/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://decadeengine.blogspot.com/2008/05/procedural-planet.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2766425237491213801/posts/default/3528675679997442376'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2766425237491213801/posts/default/3528675679997442376'/><link rel='alternate' type='text/html' href='http://decadeengine.blogspot.com/2008/05/procedural-planet.html' title='Procedural Planet'/><author><name>Ciarán McCormack</name><uri>http://www.blogger.com/profile/12300242420318331807</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://1.bp.blogspot.com/_awzb2-vllx8/SD7zfgBu-2I/AAAAAAAAAQA/SkRJIMVtszM/s72-c/planet_19_05_2008.JPG' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2766425237491213801.post-6351539500795961766</id><published>2008-04-25T20:00:00.000+01:00</published><updated>2008-04-28T20:53:03.861+01:00</updated><title type='text'>MD5 Mesh and Animation</title><content type='html'>Two young and very talented modelers from Sweden have started making some game content to be used in Decade. MD5 was their format of choice for doing animations so I used this requirement as an opportunity to research the format.&lt;br /&gt;&lt;br /&gt;A good explanation of the .md5mesh file format can be found &lt;a href="http://www.modwiki.net/wiki/MD5MESH_(file_format)"&gt;here&lt;/a&gt; and a similar explanation of .md5anim can be found &lt;a href="http://www.modwiki.net/wiki/MD5ANIM_%28file_format%29"&gt;here.&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;center&gt;&lt;object width="425" height="355"&gt;&lt;param name="movie" value="http://www.youtube.com/v/eLT-UD99B_E&amp;hl=en"&gt;&lt;/param&gt;&lt;param name="wmode" value="transparent"&gt;&lt;/param&gt;&lt;embed src="http://www.youtube.com/v/eLT-UD99B_E&amp;hl=en" type="application/x-shockwave-flash" wmode="transparent" width="425" height="355"&gt;&lt;/embed&gt;&lt;/object&gt;&lt;/center&gt;&lt;br /&gt;&lt;br /&gt;After reading the two file format descriptions specified above as well as a refresher on &lt;a href="http://en.wikipedia.org/wiki/Quaternion"&gt;quaternions&lt;/a&gt; it was not too difficult to parse the files and create the mesh and animations.&lt;br /&gt;&lt;br /&gt;In order to make Decade's MD5 support as complete as possible it supports multiple loading methods which are specified through a flag parameter in the Load function. One can build hardware/software vertex and index buffers for each specified frame at load time or they can be populated when required.&lt;br /&gt;&lt;br /&gt;If an animation does not have a high enough count of frames per second, Decade can calculate additional frames using the mesh/anim data along with &lt;a href="http://en.wikipedia.org/wiki/Quaternion"&gt;quaternions&lt;/a&gt; and &lt;a href="http://en.wikipedia.org/wiki/Slerp"&gt;slerp&lt;/a&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2766425237491213801-6351539500795961766?l=decadeengine.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://decadeengine.blogspot.com/feeds/6351539500795961766/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://decadeengine.blogspot.com/2008/04/md5-mesh-and-animation.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2766425237491213801/posts/default/6351539500795961766'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2766425237491213801/posts/default/6351539500795961766'/><link rel='alternate' type='text/html' href='http://decadeengine.blogspot.com/2008/04/md5-mesh-and-animation.html' title='MD5 Mesh and Animation'/><author><name>Ciarán McCormack</name><uri>http://www.blogger.com/profile/12300242420318331807</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2766425237491213801.post-5878521536730667781</id><published>2008-04-05T13:04:00.003+01:00</published><updated>2008-04-10T12:50:47.093+01:00</updated><title type='text'>Terrain Precalculated Shading Techniques</title><content type='html'>After adding slope lighting and seeing how simple it was to make a terrain look better with no run time cost I decided to extend this method to more realistic looking shadow/shade.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://1.bp.blogspot.com/_awzb2-vllx8/R_drVSnGRNI/AAAAAAAAAPE/Nguw-Use6nI/s1600-h/normal_05-04-2008.JPG"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;" src="http://1.bp.blogspot.com/_awzb2-vllx8/R_drVSnGRNI/AAAAAAAAAPE/Nguw-Use6nI/s400/normal_05-04-2008.JPG" border="0" alt=""id="BLOGGER_PHOTO_ID_5185731509457667282" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Above is a non shaded, non shadowed terrain. This is the control image to which the next 2 results can be compared. In this normal method a height map is procedurally generated and the terrain texture is then created from this height map and a set of layer textures.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://2.bp.blogspot.com/_awzb2-vllx8/R_drVinGROI/AAAAAAAAAPM/ojCI_pPEMSc/s1600-h/slope_05-04-2008.JPG"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;" src="http://2.bp.blogspot.com/_awzb2-vllx8/R_drVinGROI/AAAAAAAAAPM/ojCI_pPEMSc/s400/slope_05-04-2008.JPG" border="0" alt=""id="BLOGGER_PHOTO_ID_5185731513752634594" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;For slope lighting an extra step is added during the terrain texture generation.&lt;br /&gt;For each vertex of the terrain, the neighbour vertex in a specified direction is checked. If it is higher than the current vertex shade is applied. This is a relatively fast technique. In a height map of 512x512 the number of comparisons is 262144.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://3.bp.blogspot.com/_awzb2-vllx8/R_drVynGRPI/AAAAAAAAAPU/QkBwLgYGnm8/s1600-h/shadow_05-04-2008.JPG"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;" src="http://3.bp.blogspot.com/_awzb2-vllx8/R_drVynGRPI/AAAAAAAAAPU/QkBwLgYGnm8/s400/shadow_05-04-2008.JPG" border="0" alt=""id="BLOGGER_PHOTO_ID_5185731518047601906" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Shadow texture generation is an extension of the slope shading technique. Instead of checking the immediate neighbour a ray is cast from the current vertex to a specified light position. For every step along the ray the height of the terrain at this point is checked, and if it is higher than the ray shadow is applied to the original vertex. (i.e. there is no direct line of light between the light source and the vertex). In my opinion this produces more realistic results and will combine well with shadow maps or shadow volumes but it is allot slower than the previous methods. To calculate the shade applied to each vertex in the shown 512x512 terrain 45556293 checks were required, which took 27 seconds.&lt;br /&gt;&lt;br /&gt;This could probably be improved so that the terrain is checked at a lower resolution, with an approximate shade applied to the "in-between" vertices. This would allow the light source (probably the sun in an outdoor scene) to move.&lt;br /&gt;&lt;br /&gt;Decade Blog is 1 year old today. 10% of the way through its life!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2766425237491213801-5878521536730667781?l=decadeengine.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://decadeengine.blogspot.com/feeds/5878521536730667781/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://decadeengine.blogspot.com/2008/04/terrain-precalculated-shading.html#comment-form' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2766425237491213801/posts/default/5878521536730667781'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2766425237491213801/posts/default/5878521536730667781'/><link rel='alternate' type='text/html' href='http://decadeengine.blogspot.com/2008/04/terrain-precalculated-shading.html' title='Terrain Precalculated Shading Techniques'/><author><name>Ciarán McCormack</name><uri>http://www.blogger.com/profile/12300242420318331807</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://1.bp.blogspot.com/_awzb2-vllx8/R_drVSnGRNI/AAAAAAAAAPE/Nguw-Use6nI/s72-c/normal_05-04-2008.JPG' height='72' width='72'/><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2766425237491213801.post-4360099580065421495</id><published>2008-04-02T19:14:00.003+01:00</published><updated>2008-04-02T19:23:14.101+01:00</updated><title type='text'>Slope Lighting</title><content type='html'>Back at the dawn of procedural texture terrain generation in Decade I decided to skip slope lighting. My reason for this was that I have always planned on adding real lighting effects with shadow maps or shadow volumes.&lt;br /&gt;&lt;br /&gt;Reciently my long time friend and arch nemisis &lt;a href="http://jellyengine.blogspot.com/"&gt;Jelly Edwards&lt;/a&gt;, who is also now my blog enemy, has started a DX10 terrain engine and his slope lighting effect was impressive especially considering the ease at which it can be added and the free cost of this effect.&lt;br /&gt;&lt;br /&gt;Slope lighting is calculated during texture generation therefore has no cost during runtime. Each vertex in the height map is checked against its neighbour in the direction from which the light is coming. If the neighbour is higher than the current vertex shade is applied based on the difference in height (how much the terrain is facing away from the light).&lt;br /&gt;&lt;br /&gt;&lt;a href="http://1.bp.blogspot.com/_awzb2-vllx8/R_POmSnGRMI/AAAAAAAAAO8/QF6rC5CZ92U/s1600-h/slopelighting.JPG"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;" src="http://1.bp.blogspot.com/_awzb2-vllx8/R_POmSnGRMI/AAAAAAAAAO8/QF6rC5CZ92U/s400/slopelighting.JPG" border="0" alt=""id="BLOGGER_PHOTO_ID_5184714753259750594" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;I am hoping that this effect will not be used in the majority of cases, however it is a nice addition to enhance the terrain on computers which do not have the power to do real time shadows.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2766425237491213801-4360099580065421495?l=decadeengine.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://decadeengine.blogspot.com/feeds/4360099580065421495/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://decadeengine.blogspot.com/2008/04/slope-lighting.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2766425237491213801/posts/default/4360099580065421495'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2766425237491213801/posts/default/4360099580065421495'/><link rel='alternate' type='text/html' href='http://decadeengine.blogspot.com/2008/04/slope-lighting.html' title='Slope Lighting'/><author><name>Ciarán McCormack</name><uri>http://www.blogger.com/profile/12300242420318331807</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://1.bp.blogspot.com/_awzb2-vllx8/R_POmSnGRMI/AAAAAAAAAO8/QF6rC5CZ92U/s72-c/slopelighting.JPG' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2766425237491213801.post-8022580344909458102</id><published>2008-03-31T17:35:00.007+01:00</published><updated>2010-02-25T08:19:49.171Z</updated><title type='text'>Terrain Cracks Revisited</title><content type='html'>In August of last year I posted a &lt;a href="http://decadeengine.blogspot.com/2007/08/resistance-is-futile.html"&gt;blog entry&lt;/a&gt; about terrain cracks. Despite having a theory back then about how to fix this problem I never got around to fixing the issue. A new feature was always more exciting and overtook this development.&lt;br /&gt;&lt;br /&gt;Long overdue I have fixed the problem. I will briefly try and recap the issue. Segments of the terrain which are further away from the camera are rendered at a lower level of detail than those which are closer. When a patch gets a distance from the camera the level of details halves. Since every second vertex in the lower level of detail is missing this can result in cracks in the terrain. The image below shows this up close. This situation is not realistic because the patch joins will be a distance away from the camera however even at distance it is possible that artifacts would be visible.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://4.bp.blogspot.com/_awzb2-vllx8/R_Ed7inGRKI/AAAAAAAAAOs/-G8gtDyyrBk/s1600-h/cracks.jpg"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;" src="http://4.bp.blogspot.com/_awzb2-vllx8/R_Ed7inGRKI/AAAAAAAAAOs/-G8gtDyyrBk/s400/cracks.jpg" border="0" alt=""id="BLOGGER_PHOTO_ID_5183957554820433058" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;In order to overcome this problem I have removed every second vertex along the edge of a patch which has a higher level of detail. This is all calculated during load time. At run time each neighbour of a patch being rendered is examined and a bitmask is calculated accurately describing the surrounding area. This bitmask is then used to offset into an IndexBuffer array, using the correct buffer with no run time calculation required. A more complete description of this can be found in the &lt;a href="http://decadeengine.blogspot.com/2007/08/resistance-is-futile.html"&gt;previous blog entry.&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href="http://3.bp.blogspot.com/_awzb2-vllx8/R_EeASnGRLI/AAAAAAAAAO0/Zu1Hi_FSU7M/s1600-h/nocracks.JPG"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;" src="http://3.bp.blogspot.com/_awzb2-vllx8/R_EeASnGRLI/AAAAAAAAAO0/Zu1Hi_FSU7M/s400/nocracks.JPG" border="0" alt=""id="BLOGGER_PHOTO_ID_5183957636424811698" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;As can be seen above, there are now no visible joints between patches of differing detail, resulting in a more natural terrain.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2766425237491213801-8022580344909458102?l=decadeengine.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://decadeengine.blogspot.com/feeds/8022580344909458102/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://decadeengine.blogspot.com/2008/03/terrain-cracks-revisited.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2766425237491213801/posts/default/8022580344909458102'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2766425237491213801/posts/default/8022580344909458102'/><link rel='alternate' type='text/html' href='http://decadeengine.blogspot.com/2008/03/terrain-cracks-revisited.html' title='Terrain Cracks Revisited'/><author><name>Ciarán McCormack</name><uri>http://www.blogger.com/profile/12300242420318331807</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://4.bp.blogspot.com/_awzb2-vllx8/R_Ed7inGRKI/AAAAAAAAAOs/-G8gtDyyrBk/s72-c/cracks.jpg' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2766425237491213801.post-5915206989734745784</id><published>2008-03-25T15:47:00.002Z</published><updated>2008-03-25T16:02:36.930Z</updated><title type='text'>General Update</title><content type='html'>Time flies by again. Its been a busy year so far, allot of projects approaching deadlines at the office and I also worked allot on a 2D fluid dynamics tech demo. Development on Decade still continues, however currently at a slow pace.&lt;br /&gt;&lt;br /&gt;In the past month I haven't had allot of time to complete 'Parallel Split Shadow Maps', so this is still in a limbo state. They sort of work however sometimes the scene is a mess and other times there are unknown artifacts. &lt;br /&gt;&lt;br /&gt;While making the 2d fluid dynamics demo, with the &lt;a href="http://www.playfirst.com"&gt;PlayFirst SDK&lt;/a&gt;, I was impressed with their usage of LUA scripting. I have researched this topic a little and feel that I will add support for &lt;a href="http://www.somedude.net/gamemonkey/"&gt;Game Monkey&lt;/a&gt; to Decade. As with the graphics and physics layers the script engine will also be extrapolated away so I can, at a later date, add support for another script engine.&lt;br /&gt;&lt;br /&gt;I have also added joypad support to Decade to avoid always having to use the keyboard and mouse. DirectInput was used for this so this functionality will not be added to the Ubuntu version any time soon, or until I at least figure out how to do this in Linux.&lt;br /&gt;&lt;br /&gt;I am delighted to announce that a friend has at last got on the game engine band wagon and started his own terrain engine called &lt;a href="http://jellyengine.blogspot.com/"&gt;Jelly Engine&lt;/a&gt;. His ultimate goal is to generate a procedural universe. Please have a look at this blog and give him grief on how bad his engine is, even though it would be a lie.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2766425237491213801-5915206989734745784?l=decadeengine.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://decadeengine.blogspot.com/feeds/5915206989734745784/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://decadeengine.blogspot.com/2008/03/general-update.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2766425237491213801/posts/default/5915206989734745784'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2766425237491213801/posts/default/5915206989734745784'/><link rel='alternate' type='text/html' href='http://decadeengine.blogspot.com/2008/03/general-update.html' title='General Update'/><author><name>Ciarán McCormack</name><uri>http://www.blogger.com/profile/12300242420318331807</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2766425237491213801.post-2980315538573864260</id><published>2008-02-18T17:01:00.001Z</published><updated>2008-04-10T13:01:46.045+01:00</updated><title type='text'>Shadows</title><content type='html'>Having past experience with Shadow Volumes in DirectX I could see a potential issue in using this technique in Decade so I therefore focused my attention on Shadow Maps.&lt;br /&gt;&lt;br /&gt;Before giving some detail on my shadow map implementation I will briefly describe why I have bypassed Shadow Volumes for now. Shadow Volumes are created by calculating a silhouette of the mesh from the lights point of view. This silhouette is generated from the raw mesh data. The low poly trees currently used in Decade consist of colour keyed faces. The resulting Shadow Volume generates a shadow of the full face and not just the visible (non blended area). Below is a faked image which shows the shadow that would be generated using the Shadow Volume technique. Notice that the shadow for the tree remains the same regardless if colour keying is enabled or not.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://2.bp.blogspot.com/_awzb2-vllx8/R6yNM5F8ONI/AAAAAAAAAOM/AY2jal-hbxI/s1600-h/shadowsvolumes1.JPG"&gt;&lt;img id="BLOGGER_PHOTO_ID_5164658125310802130" style="DISPLAY: block; MARGIN: 0px auto 10px; CURSOR: hand; TEXT-ALIGN: center" alt="" src="http://2.bp.blogspot.com/_awzb2-vllx8/R6yNM5F8ONI/AAAAAAAAAOM/AY2jal-hbxI/s400/shadowsvolumes1.JPG" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Shadow Maps generate shadows by rendering the scene from the lights point of view and saving the depth buffer to a texture. This texture is then used to shadow the scene. The advantages that Shadow Maps have over Shadow Volumes are&lt;br /&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;No colour keying issues&lt;/li&gt;&lt;li&gt;Complex geometry does not affect the performance of the algorithm. The scene rendering should be efficient as it must be rendered 3 time per light&lt;br /&gt;&lt;ul&gt;From Lights point of view. Depth Buffer saved to Texture&lt;br /&gt;From Cameras point of view with only ambient lighting.&lt;br /&gt;From Cameras point of view with light enabled and Shadow Map applied.&lt;/ul&gt;&lt;br /&gt;&lt;br /&gt;&lt;br&gt;The complexity of the geometry is of much higher importance in Shadow Volumes because as mentioned previously the silhouette is generated from the raw mesh data&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;a href="http://1.bp.blogspot.com/_awzb2-vllx8/R6yNNpF8OOI/AAAAAAAAAOU/4VogcGIAs94/s1600-h/shadows1.JPG"&gt;&lt;img id="BLOGGER_PHOTO_ID_5164658138195704034" style="DISPLAY: block; MARGIN: 0px auto 10px; CURSOR: hand; TEXT-ALIGN: center" alt="" src="http://1.bp.blogspot.com/_awzb2-vllx8/R6yNNpF8OOI/AAAAAAAAAOU/4VogcGIAs94/s400/shadows1.JPG" border="0" /&gt;&lt;/a&gt;&lt;/p&gt;&lt;p&gt;Due to the limited resolution of the texture map holding the depth/shadow data Shadow Maps can and usually do result in very aliased shadows. In the image below the light is only 75 units from the scene however it is very evident from looking at the car shadow that the shadow quality is very low. The right image shows the depth buffer from the lights point of view which is used to render the shadows.&lt;/p&gt;&lt;p&gt;&lt;a href="http://2.bp.blogspot.com/_awzb2-vllx8/R6yNN5F8OPI/AAAAAAAAAOc/L-8xKxPRFgg/s1600-h/shadows2.JPG"&gt;&lt;img id="BLOGGER_PHOTO_ID_5164658142490671346" style="DISPLAY: block; MARGIN: 0px auto 10px; CURSOR: hand; TEXT-ALIGN: center" alt="" src="http://2.bp.blogspot.com/_awzb2-vllx8/R6yNN5F8OPI/AAAAAAAAAOc/L-8xKxPRFgg/s400/shadows2.JPG" border="0" /&gt;&lt;/a&gt;&lt;/p&gt;&lt;p&gt;Below can be seen how the Shadow Mapping technique becomes unusable as the light source moves further away from the scene or as the scene boundary grows. With less shadow map pixels used to represent the shadow of the same area of space the shadow loses form and any relationship with the casting object.&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;a href="http://2.bp.blogspot.com/_awzb2-vllx8/R6yNN5F8OQI/AAAAAAAAAOk/gNhCg9HraQs/s1600-h/shadows4.JPG"&gt;&lt;img id="BLOGGER_PHOTO_ID_5164658142490671362" style="DISPLAY: block; MARGIN: 0px auto 10px; CURSOR: hand; TEXT-ALIGN: center" alt="" src="http://2.bp.blogspot.com/_awzb2-vllx8/R6yNN5F8OQI/AAAAAAAAAOk/gNhCg9HraQs/s400/shadows4.JPG" border="0" /&gt;&lt;/a&gt;&lt;/p&gt;&lt;p&gt;These issues make the Shadow Mapping technique inappropriate for rendering any large outdoor scene. Further research has shown that Shadow Mapping has some advanced friends such as Parallel Split Shadow Mapping. (PSSM). The PSSM method involves splitting the frustum into several parts along the eye vector, and rendering a separate Shadow Map for each split. This allows the area closest to the camera to use higher resolution shadow maps and with the resulting Shadow Map stretched over a much smaller area, less aliased shadows are possible.&lt;br /&gt;&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2766425237491213801-2980315538573864260?l=decadeengine.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://decadeengine.blogspot.com/feeds/2980315538573864260/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://decadeengine.blogspot.com/2008/02/shadows_08.html#comment-form' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2766425237491213801/posts/default/2980315538573864260'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2766425237491213801/posts/default/2980315538573864260'/><link rel='alternate' type='text/html' href='http://decadeengine.blogspot.com/2008/02/shadows_08.html' title='Shadows'/><author><name>Ciarán McCormack</name><uri>http://www.blogger.com/profile/12300242420318331807</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://2.bp.blogspot.com/_awzb2-vllx8/R6yNM5F8ONI/AAAAAAAAAOM/AY2jal-hbxI/s72-c/shadowsvolumes1.JPG' height='72' width='72'/><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2766425237491213801.post-7398513936698636355</id><published>2008-01-12T22:28:00.000Z</published><updated>2008-01-19T22:56:04.587Z</updated><title type='text'>Car Physics</title><content type='html'>&lt;div align="left"&gt;Using Joints in &lt;a href="http://www.ode.org/"&gt;ODE&lt;/a&gt; basic car physics has been added to Decade. This consists of a car body and 4 wheels. Each wheel is connected to the car body by a combination of 2 joints. These emulate the suspension, steering and the &lt;span class="blsp-spelling-corrected" id="SPELLING_ERROR_0"&gt;axle&lt;/span&gt;.&lt;/div&gt;&lt;br /&gt;&lt;div align="left"&gt;A known issue with &lt;a href="http://www.ode.org/"&gt;ODE&lt;/a&gt; is that when assigning a mass to a rigid body, the center of mass must be (0,0,0) relative to the body’s position. This results in the center of gravity of the car being much to high causing frequent rolls when turning at speed. Top Gear would have a great time comparing the car to some American sports car which has great straight line speed but corners with the grace of a giraffe.&lt;/div&gt;&lt;div align="left"&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;center&gt;&lt;object height="355" width="425"&gt;&lt;param name="movie" value="http://www.youtube.com/v/KE-BBxXLz-8&amp;amp;rel=1"&gt;&lt;param name="wmode" value="transparent"&gt;&lt;embed src="http://www.youtube.com/v/KE-BBxXLz-8&amp;rel=1" type="application/x-shockwave-flash" wmode="transparent" width="425" height="355"&gt;&lt;/embed&gt;&lt;/object&gt;&lt;/center&gt;&lt;center&gt;&lt;/center&gt;&lt;br /&gt;&lt;br /&gt;&lt;div align="left"&gt;If you note in the video at time 30 seconds, the car is represented to the physics engine as a box. Even when this box is reduced to tightly surround the car the center of mass will still be too high. I feel that if I create a thin box at the bottom of the car, which has 90% the mass of the car, to which the wheels are attached, and connected to this by a fixed joint is the light car body, driving should be &lt;span class="blsp-spelling-corrected" id="SPELLING_ERROR_1"&gt;allot&lt;/span&gt; smoother and realistic.&lt;/div&gt;&lt;br /&gt;&lt;div align="left"&gt;A fixed Joint is defined as "&lt;em&gt;The fixed joint maintains a fixed relative position and orientation between two bodies, or between a body and the static environment."&lt;/em&gt;&lt;/div&gt;&lt;br /&gt;&lt;div align="left"&gt;As well as this representation working well in Decade it also &lt;span class="blsp-spelling-corrected" id="SPELLING_ERROR_2"&gt;closely&lt;/span&gt; copies real life, with the thin box being the chassis and the larger box, being the much lighter body.&lt;/div&gt;&lt;br /&gt;&lt;div align="left"&gt;Car model was downloaded from &lt;a href="http://www.turbosquid.com/Search/Index.cfm/FuseAction/ProcessSmartSearch/intMediaType/2/stgType/Free"&gt;Turbo Squid&lt;/a&gt; which &lt;span class="blsp-spelling-corrected" id="SPELLING_ERROR_0"&gt;as well&lt;/span&gt; as selling an excellent range of models, also offers a selection of models for free.&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2766425237491213801-7398513936698636355?l=decadeengine.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://decadeengine.blogspot.com/feeds/7398513936698636355/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://decadeengine.blogspot.com/2008/01/car-physics.html#comment-form' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2766425237491213801/posts/default/7398513936698636355'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2766425237491213801/posts/default/7398513936698636355'/><link rel='alternate' type='text/html' href='http://decadeengine.blogspot.com/2008/01/car-physics.html' title='Car Physics'/><author><name>Ciarán McCormack</name><uri>http://www.blogger.com/profile/12300242420318331807</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2766425237491213801.post-4989879788566298842</id><published>2007-12-23T18:10:00.001Z</published><updated>2007-12-23T20:37:48.017Z</updated><title type='text'>Ubuntu</title><content type='html'>In an effort to use &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_0"&gt;OpenGL&lt;/span&gt; to its full potential, and a feature that is unique to &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_1"&gt;OpenGL&lt;/span&gt; over its main competitor &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_2"&gt;DirectX&lt;/span&gt;, I have decided to create a non windows version of Decade. Over the weekend I downloaded &lt;a href="http://www.ubuntu.com/"&gt;&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_3"&gt;Ubuntu&lt;/span&gt;&lt;/a&gt; which is a free community developed, &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_4"&gt;linux&lt;/span&gt;-based operating system.&lt;br /&gt;&lt;br /&gt;Instead of making my desktop dual boot, I decided to try and use &lt;a href="http://www.microsoft.com/windows/products/winfamily/virtualpc/default.mspx"&gt;Microsoft Virtual PC&lt;/a&gt;, which is also free to download. It was a very easy to create the virtual PC, virtual &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_5"&gt;hardisk&lt;/span&gt; and install &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_6"&gt;Ubuntu&lt;/span&gt;. I can now access my &lt;a href="http://www.ubuntu.com/"&gt;&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_7"&gt;Ubuntu&lt;/span&gt;&lt;/a&gt; &lt;span class="blsp-spelling-corrected" id="SPELLING_ERROR_8"&gt;installation&lt;/span&gt; from within my windows &lt;span class="blsp-spelling-corrected" id="SPELLING_ERROR_9"&gt;environment&lt;/span&gt; getting the &lt;span class="blsp-spelling-corrected" id="SPELLING_ERROR_10"&gt;benefits&lt;/span&gt; of both systems.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://2.bp.blogspot.com/_awzb2-vllx8/R26klqan7zI/AAAAAAAAAMw/XJJ7dWu-gj8/s1600-h/ubuntu.JPG"&gt;&lt;img id="BLOGGER_PHOTO_ID_5147232391079128882" style="DISPLAY: block; MARGIN: 0px auto 10px; CURSOR: hand; TEXT-ALIGN: center" alt="" src="http://2.bp.blogspot.com/_awzb2-vllx8/R26klqan7zI/AAAAAAAAAMw/XJJ7dWu-gj8/s400/ubuntu.JPG" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;It took a little effort to get networking enabled, my router requiring some setting changes however once this was complete it was again a simple process to connect over the local network and access the shared drives on my Windows PC. With this setup I hope to use the same source base for Win Decade and &lt;a href="http://www.ubuntu.com/"&gt;&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_11"&gt;Ubuntu&lt;/span&gt;&lt;/a&gt; Decade.&lt;br /&gt;&lt;br /&gt;My first job after leaving university was in a &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_12"&gt;HPUX&lt;/span&gt; &lt;span class="blsp-spelling-corrected" id="SPELLING_ERROR_13"&gt;environment&lt;/span&gt; however being a number of years ago I have forgotten &lt;span class="blsp-spelling-corrected" id="SPELLING_ERROR_14"&gt;allot&lt;/span&gt; of the basics. This morning I created the &lt;span class="blsp-spelling-corrected" id="SPELLING_ERROR_15"&gt;obligatory&lt;/span&gt; "Hello World" C++ program, but am having problems building &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_16"&gt;OpenGL&lt;/span&gt; and &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_17"&gt;SDL&lt;/span&gt; projects.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2766425237491213801-4989879788566298842?l=decadeengine.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://decadeengine.blogspot.com/feeds/4989879788566298842/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://decadeengine.blogspot.com/2007/12/ubuntu.html#comment-form' title='5 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2766425237491213801/posts/default/4989879788566298842'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2766425237491213801/posts/default/4989879788566298842'/><link rel='alternate' type='text/html' href='http://decadeengine.blogspot.com/2007/12/ubuntu.html' title='Ubuntu'/><author><name>Ciarán McCormack</name><uri>http://www.blogger.com/profile/12300242420318331807</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://2.bp.blogspot.com/_awzb2-vllx8/R26klqan7zI/AAAAAAAAAMw/XJJ7dWu-gj8/s72-c/ubuntu.JPG' height='72' width='72'/><thr:total>5</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2766425237491213801.post-3985513723689714798</id><published>2007-12-15T11:47:00.000Z</published><updated>2007-12-22T12:13:34.726Z</updated><title type='text'>Decade Meets ODE</title><content type='html'>Time yet again ticks by. No matter now much I try I can't stop it. As you can see Novermber was a quiet month in the life of Decade. Due to personal reasons I did not have much if any time to program, however last week I returned to Decade and decided that it was long overdue to add some physics to the engine.&lt;br /&gt;&lt;br /&gt;Having messed around with &lt;a href="http://www.ode.org/"&gt;ODE&lt;/a&gt; (Open Dynamics Engine) a few years ago I decided that I would start with this free physics engine. I am trying to use the same approach in adding the physics as I did with the graphics. I have implemented an extrapolation layer between the game engine and the physics engine with the hope that in the future I can add support for other physics engines without having to change too much of the game code.&lt;br /&gt;&lt;br /&gt;Refreshing myself with the theory of &lt;a href="http://www.ode.org/"&gt;ODE&lt;/a&gt; last week I have now started to modify Decade. Up to now all transformations, rotations etc.. in Decade were stored as Eulars. &lt;a href="http://www.ode.org/"&gt;ODE&lt;/a&gt; rotations are matrix based so rather than have converter functions to change between Eular-&gt;Matrix and Matrix-&gt;Euler I modified the Decade core so that each object builds its own Model View Matrix. The Projection and View matrices are also build and handled by Decade. Although a little more complicated to code and read this approach does have some advantages. For an object which is static in the world its matrix can be built once, reused time and time again and doesn't have to be updated until the object moves. Using the &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_0"&gt;glRotate&lt;/span&gt;, &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_1"&gt;glScale&lt;/span&gt; and &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_2"&gt;glTranslate&lt;/span&gt; functions this matrix was built for each object every frame.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;center&gt;&lt;object height="355" width="425"&gt;&lt;param name="movie" value="http://www.youtube.com/v/QSgR0s7zqFo&amp;amp;rel=1"&gt;&lt;param name="wmode" value="transparent"&gt;&lt;embed src="http://www.youtube.com/v/QSgR0s7zqFo&amp;rel=1" type="application/x-shockwave-flash" wmode="transparent" width="425" height="355"&gt;&lt;/embed&gt;&lt;/object&gt;&lt;/center&gt;&lt;center&gt;&lt;/center&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;div align="left"&gt;Now that the basics of &lt;a href="http://www.ode.org/"&gt;ODE&lt;/a&gt; have been added I will continue on this course building my Physics Layer. I will create some simple rag doll physics or a vehicle which will introduce me to the topic of joints.&lt;/div&gt;&lt;div align="left"&gt;&lt;/div&gt;&lt;div align="left"&gt;After basic physics is added to Decade I really must invest some time to complete my to do list of improvements on current features. This includes &lt;/div&gt;&lt;ul&gt;&lt;li&gt;&lt;div align="left"&gt;Properly fixing cracks in &lt;span class="blsp-spelling-corrected" id="SPELLING_ERROR_3"&gt;terrain&lt;/span&gt; &lt;/div&gt;&lt;/li&gt;&lt;li&gt;&lt;div align="left"&gt;Priority Rendering Queue&lt;/div&gt;&lt;/li&gt;&lt;li&gt;&lt;div align="left"&gt;&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_4"&gt;Octree&lt;/span&gt; V &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_5"&gt;Quadtree&lt;/span&gt;&lt;/div&gt;&lt;/li&gt;&lt;li&gt;&lt;div align="left"&gt;ROAM Terrain&lt;/div&gt;&lt;/li&gt;&lt;li&gt;&lt;div align="left"&gt;Finish Shadow Volumes and Parallel Split Shadow &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_6"&gt;Maps&lt;/span&gt; &lt;/div&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p align="left"&gt;and after that I need to continue with my future to do list&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;div align="left"&gt;&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_7"&gt;Scriptable&lt;/span&gt; Particle System and Editor&lt;/div&gt;&lt;/li&gt;&lt;li&gt;&lt;div align="left"&gt;Planet Generation&lt;/div&gt;&lt;/li&gt;&lt;li&gt;&lt;div align="left"&gt;Some small tech games (Golf, racing etc...)&lt;/div&gt;&lt;/li&gt;&lt;/ul&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2766425237491213801-3985513723689714798?l=decadeengine.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://decadeengine.blogspot.com/feeds/3985513723689714798/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://decadeengine.blogspot.com/2007/12/decade-meets-ode.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2766425237491213801/posts/default/3985513723689714798'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2766425237491213801/posts/default/3985513723689714798'/><link rel='alternate' type='text/html' href='http://decadeengine.blogspot.com/2007/12/decade-meets-ode.html' title='Decade Meets ODE'/><author><name>Ciarán McCormack</name><uri>http://www.blogger.com/profile/12300242420318331807</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2766425237491213801.post-2667706981757050864</id><published>2007-10-30T20:29:00.000Z</published><updated>2007-10-30T21:25:18.997Z</updated><title type='text'>Atmospheric Scattering</title><content type='html'>&lt;div align="left"&gt;At long long last I have got a grip of atmospheric scattering. Decades implementation of atmospheric scattering is based on &lt;a href="http://sponeil.net/"&gt;Sean O'Neill's&lt;/a&gt; amazing research. In the video below you can see the sun rising in the sky as the camera moves around the planet. The word planet is used with grace as the planet is simply a smooth sphere which was procedurally generated with recursive subdivision. (See Post below). Close to the end of the video the rendering switches to wire frame and you can see the planet subdividing by another level.&lt;/div&gt;&lt;div align="left"&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;center&gt;&lt;object height="355" width="425"&gt;&lt;param name="movie" value="http://www.youtube.com/v/JvQ44lvzmk0"&gt;&lt;param name="wmode" value="transparent"&gt;&lt;embed src="http://www.youtube.com/v/JvQ44lvzmk0" type="application/x-shockwave-flash" wmode="transparent" width="425" height="355"&gt;&lt;/embed&gt;&lt;/object&gt;&lt;/center&gt;&lt;center&gt;&lt;/center&gt;&lt;div align="left"&gt;&lt;/div&gt;&lt;div align="left"&gt;&lt;br /&gt;&lt;br /&gt;As always there is a list of improvements to make. The planet is currently rendered in software, each face rendered separately. There is also no culling. Adding hardware acceleration and efficient culling should greatly improve performance. The subdivided implementation of the sphere allows easy culling of vast numbers of faces with a few checks.&lt;/div&gt;&lt;div align="left"&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;div align="left"&gt;I am also going to look more detailed at realtime fractal terrain generation, possibly with Perlin Noise so as I dubdivide the planet as the camera gets closer the result will be a details, rich looking terrain.&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2766425237491213801-2667706981757050864?l=decadeengine.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://decadeengine.blogspot.com/feeds/2667706981757050864/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://decadeengine.blogspot.com/2007/10/atmospheric-scattering.html#comment-form' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2766425237491213801/posts/default/2667706981757050864'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2766425237491213801/posts/default/2667706981757050864'/><link rel='alternate' type='text/html' href='http://decadeengine.blogspot.com/2007/10/atmospheric-scattering.html' title='Atmospheric Scattering'/><author><name>Ciarán McCormack</name><uri>http://www.blogger.com/profile/12300242420318331807</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2766425237491213801.post-4208051077776264774</id><published>2007-10-24T20:46:00.000+01:00</published><updated>2007-10-24T21:22:54.014+01:00</updated><title type='text'>Procedural Sphere</title><content type='html'>While implementing my Sky Dome for atmospheric Scattering a number of issue quickly became noticeable. A sphere generated using the OpenGL function gluSphere or loaded from a mesh file had vertex compression at the poles. This usually causes texture compression/distortion which is naturally very undesirable.&lt;br /&gt;&lt;br /&gt;To maintain Decade's procedural capability and to remove the issues with the previous implementation I created my own Sphere function by recursively subdividing a cube until the required resolution was achieved.&lt;br /&gt;&lt;br /&gt;Below the two solutions can be seen side by side. On the left is the Sphere created with gluSphere or loaded from a file. The vertex compression is immediately obvious. The size of the face depends on which segment it exists, with faces getting smaller closer to the poles. On the right is my procedurally generated sphere. As you can see there is no vertex compression at the pole. In fact no pole is visually obvious. Due to the subdividing nature of the algorithm each face in the sphere is the exact same size.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://1.bp.blogspot.com/_awzb2-vllx8/Rx-hPo41t2I/AAAAAAAAAMA/jSFOmXqw78o/s1600-h/sphere.JPG"&gt;&lt;img id="BLOGGER_PHOTO_ID_5124992191016843106" style="DISPLAY: block; MARGIN: 0px auto 10px; CURSOR: hand; TEXT-ALIGN: center" alt="" src="http://1.bp.blogspot.com/_awzb2-vllx8/Rx-hPo41t2I/AAAAAAAAAMA/jSFOmXqw78o/s400/sphere.JPG" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;I believe I may have achieved allot more than just creating a sky dome with this implementation. Creating a universe with procedural planets has always been on the wish list for Decade but I never knew where to begin. The recursive subdivision appears to be an ideal solution for this. It has level of detail and efficient culling properties automatically built in.&lt;br /&gt;&lt;br /&gt;The level of the quad tree rendered defines the level of detail of the planet. Since the root of the planet is 6 quads, it is easy to bounds check these against the frustum and quickly remove unseen areas of the planet and the same process can be repeated for each of the child levels of the quad tree.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://3.bp.blogspot.com/_awzb2-vllx8/Rx-hQI41t3I/AAAAAAAAAMI/VcVLpBUNNnw/s1600-h/mesh_division.JPG"&gt;&lt;img id="BLOGGER_PHOTO_ID_5124992199606777714" style="DISPLAY: block; MARGIN: 0px auto 10px; CURSOR: hand; TEXT-ALIGN: center" alt="" src="http://3.bp.blogspot.com/_awzb2-vllx8/Rx-hQI41t3I/AAAAAAAAAMI/VcVLpBUNNnw/s400/mesh_division.JPG" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;By using the above algorithm along with some height maps I believe rendering a full planet should be possible. I look forward to the day when I can roam a planet in Decade then jump in a space ship, fly away and land on another planet.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2766425237491213801-4208051077776264774?l=decadeengine.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://decadeengine.blogspot.com/feeds/4208051077776264774/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://decadeengine.blogspot.com/2007/10/procedural-sphere.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2766425237491213801/posts/default/4208051077776264774'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2766425237491213801/posts/default/4208051077776264774'/><link rel='alternate' type='text/html' href='http://decadeengine.blogspot.com/2007/10/procedural-sphere.html' title='Procedural Sphere'/><author><name>Ciarán McCormack</name><uri>http://www.blogger.com/profile/12300242420318331807</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://1.bp.blogspot.com/_awzb2-vllx8/Rx-hPo41t2I/AAAAAAAAAMA/jSFOmXqw78o/s72-c/sphere.JPG' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2766425237491213801.post-8483876889658781400</id><published>2007-10-21T23:09:00.000+01:00</published><updated>2007-10-24T08:35:04.945+01:00</updated><title type='text'>Oil Painting</title><content type='html'>For another personal project (web based) I have worked on some image processing, hence the lack of updates this month. Rather than let the new code go to waste I have applied it to Decade too see the results. Here is a normal screen shot of Decade&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;&lt;a href="http://4.bp.blogspot.com/_awzb2-vllx8/Rx4d8o41tyI/AAAAAAAAALg/vLUlesuZDSQ/s1600-h/normal_painting.JPG"&gt;&lt;img id="BLOGGER_PHOTO_ID_5124566353599379234" style="DISPLAY: block; MARGIN: 0px auto 10px; CURSOR: hand; TEXT-ALIGN: center" alt="" src="http://4.bp.blogspot.com/_awzb2-vllx8/Rx4d8o41tyI/AAAAAAAAALg/vLUlesuZDSQ/s400/normal_painting.JPG" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;and here is Decade as an Oil Painting.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://1.bp.blogspot.com/_awzb2-vllx8/Rx4d8441tzI/AAAAAAAAALo/KSJ2pto2Y_g/s1600-h/oil_painting.JPG"&gt;&lt;img id="BLOGGER_PHOTO_ID_5124566357894346546" style="DISPLAY: block; MARGIN: 0px auto 10px; CURSOR: hand; TEXT-ALIGN: center" alt="" src="http://1.bp.blogspot.com/_awzb2-vllx8/Rx4d8441tzI/AAAAAAAAALo/KSJ2pto2Y_g/s400/oil_painting.JPG" border="0" /&gt;&lt;/a&gt; &lt;/p&gt;&lt;p&gt;I am happy with the results, although now a little unsatisfied that the manipulation is not real time. I'm not sure of the possibility of writing a Pixel Script to do this in real time because it requires sampling multiple pixels in order to create the smudged Oil Paint effect. Despite this I still plan to at least try and implement an Oil Painting script sometime. It would be nice to make a game where it appears that the whole world is painted, and perhaps the levels of the game could be based on classic painting by &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_0"&gt;Da&lt;/span&gt; &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_1"&gt;Vinci&lt;/span&gt;, Picasso etc. &lt;/p&gt;&lt;p&gt;&lt;br /&gt;I have also been working on Atmospheric Scattering this month but because of my other commitments have not yet fully integrated with Decade. I will try and get a video update soon to at least give a taster of my progress.&lt;/p&gt;&lt;p&gt;The other day I found a shortcut to my &lt;a href="http://www.ciaranmccormack.tk/"&gt;old website&lt;/a&gt;. It has been almost 3 years since it was updated. Hosted on an Irish telecoms provider, I do not seem to be able &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_2"&gt;login&lt;/span&gt; to my account from outside Ireland so it has remained static since I left. It has some fond memories for me. This was my start in game programming as a hobby. The host where my game demos were stored is no longer active so you cannot download anything. If you would like to try anything leave a comment and let me know. I will then find the game in my archive and upload it.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2766425237491213801-8483876889658781400?l=decadeengine.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://decadeengine.blogspot.com/feeds/8483876889658781400/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://decadeengine.blogspot.com/2007/10/oil-painting.html#comment-form' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2766425237491213801/posts/default/8483876889658781400'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2766425237491213801/posts/default/8483876889658781400'/><link rel='alternate' type='text/html' href='http://decadeengine.blogspot.com/2007/10/oil-painting.html' title='Oil Painting'/><author><name>Ciarán McCormack</name><uri>http://www.blogger.com/profile/12300242420318331807</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://4.bp.blogspot.com/_awzb2-vllx8/Rx4d8o41tyI/AAAAAAAAALg/vLUlesuZDSQ/s72-c/normal_painting.JPG' height='72' width='72'/><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2766425237491213801.post-8384289367995830423</id><published>2007-09-24T13:32:00.000+01:00</published><updated>2007-09-24T13:48:01.748+01:00</updated><title type='text'>Underwater Caustics</title><content type='html'>Caustics are defined as "The light patterns generated on a surface by reflected or refracted light rays." Imaging that you are in a swimming pool and swimming beneath the water. The sides of the pool are not evenly lit. As the light enters through the surface of the water it is refracted and causes areas of shadow to appear on any surface beneath the water line.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;This implementation of caustics is physically fake. I do not represent light beams entering and refracting on the water surface. This effect is achieved by tiling a sequence of textures on the terrain for the area under the surface of the water.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;div align="center"&gt;&lt;a href="http://2.bp.blogspot.com/_awzb2-vllx8/Rvewqj22uHI/AAAAAAAAALY/EM1r1_ZceJM/s1600-h/caust.JPG"&gt;&lt;img id="BLOGGER_PHOTO_ID_5113750147128801394" style="DISPLAY: block; MARGIN: 0px auto 10px; CURSOR: hand; TEXT-ALIGN: center" alt="" src="http://2.bp.blogspot.com/_awzb2-vllx8/Rvewqj22uHI/AAAAAAAAALY/EM1r1_ZceJM/s400/caust.JPG" border="0" /&gt;&lt;/a&gt;&lt;span style="font-size:78%;"&gt;Sequence of textures which are tiled over the terrain&lt;/span&gt;&lt;/div&gt;&lt;br /&gt;&lt;div align="left"&gt;This does require the graphics card to support a 3rd texture unit. If you remember from previous blog entries, the terrain already requires 2 texture units, 1 for the terrain texture and 1 for the detail map to add more realism to the scene. From some quick research it looks as though most modern graphics cards support at least 4 texture units so this should not be a problem.&lt;br /&gt;&lt;/div&gt;&lt;p align="center"&gt;&lt;object height="350" width="425"&gt;&lt;param name="movie" value="http://www.youtube.com/v/DPlNS_x7mfM"&gt;&lt;param name="wmode" value="transparent"&gt;&lt;br /&gt;&lt;br /&gt;&lt;embed src="http://www.youtube.com/v/DPlNS_x7mfM" type="application/x-shockwave-flash" wmode="transparent" width="425" height="350"&gt;&lt;/embed&gt;&lt;/object&gt;&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2766425237491213801-8384289367995830423?l=decadeengine.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://decadeengine.blogspot.com/feeds/8384289367995830423/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://decadeengine.blogspot.com/2007/09/underwater-caustics.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2766425237491213801/posts/default/8384289367995830423'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2766425237491213801/posts/default/8384289367995830423'/><link rel='alternate' type='text/html' href='http://decadeengine.blogspot.com/2007/09/underwater-caustics.html' title='Underwater Caustics'/><author><name>Ciarán McCormack</name><uri>http://www.blogger.com/profile/12300242420318331807</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://2.bp.blogspot.com/_awzb2-vllx8/Rvewqj22uHI/AAAAAAAAALY/EM1r1_ZceJM/s72-c/caust.JPG' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2766425237491213801.post-2714910328903486633</id><published>2007-09-22T15:33:00.000+01:00</published><updated>2007-09-23T13:51:26.487+01:00</updated><title type='text'>Water Comparison</title><content type='html'>&lt;div align="left"&gt;With both my planned implementations of water nearing completion it seemed appropriate to run some comparisons.&lt;br /&gt;&lt;br /&gt;CPUWater was coded so that Decade could render a terrain with water on PCs which do not support the relevant OpenGL Extensions required for GPUWater. Decade will automatically detect which it can use.&lt;br /&gt;&lt;br /&gt;The main surprise to come from running this comparison is non technical. After a few friends and programming peers viewed my comparison video (below) approximately 80% if them commented on how good CPUWater looked and that they thought it looked more realistic than GPUWater.&lt;br /&gt;&lt;br /&gt;&lt;/div&gt;&lt;div align="center"&gt;&lt;a href="http://3.bp.blogspot.com/_awzb2-vllx8/RvUoIT22uDI/AAAAAAAAAK4/xLVNybUCYB4/s1600-h/CPU_Water_Comparison.JPG"&gt;&lt;img id="BLOGGER_PHOTO_ID_5113037075183482930" style="DISPLAY: block; MARGIN: 0px auto 10px; CURSOR: hand; TEXT-ALIGN: center" alt="" src="http://3.bp.blogspot.com/_awzb2-vllx8/RvUoIT22uDI/AAAAAAAAAK4/xLVNybUCYB4/s400/CPU_Water_Comparison.JPG" border="0" /&gt;&lt;/a&gt; &lt;span style="font-size:78%;"&gt;Scene Rendered with CPU Water&lt;/span&gt;&lt;/div&gt;&lt;div align="center"&gt;&lt;span style="font-size:78%;"&gt;&lt;/span&gt;&lt;span style="font-size:78%;"&gt;&lt;/div&gt;&lt;/span&gt;&lt;div align="center"&gt;&lt;br /&gt;&lt;/div&gt;&lt;a href="http://4.bp.blogspot.com/_awzb2-vllx8/RvUoIj22uEI/AAAAAAAAALA/bXfgHT-ioI0/s1600-h/GPU_Water_Comparison.JPG"&gt;&lt;img id="BLOGGER_PHOTO_ID_5113037079478450242" style="DISPLAY: block; MARGIN: 0px auto 10px; CURSOR: hand; TEXT-ALIGN: center" alt="" src="http://4.bp.blogspot.com/_awzb2-vllx8/RvUoIj22uEI/AAAAAAAAALA/bXfgHT-ioI0/s400/GPU_Water_Comparison.JPG" border="0" /&gt; &lt;p align="center"&gt;&lt;/a&gt;&lt;/p&gt;&lt;p align="center"&gt;&lt;span style="font-size:78%;"&gt;Scene Rendered with GPU Water&lt;/span&gt;&lt;span style="font-size:78%;"&gt; &lt;/p&gt;&lt;p align="left"&gt;&lt;br /&gt;&lt;/p&gt;&lt;/span&gt;The main reason for this is because CPU water moves. Its height at each point varies depending on the tessellation of the mesh therefore it looks like waves lapping the shore. Since GPU water is comprised on only 1 quad and the waves are simulated using bump mapping the shore line is static.&lt;br /&gt;&lt;br /&gt;Perhaps I should write a CPUGPUWater. The water will comprise of a tessellating mesh like CPU water, but it will be rendered using bump mapping like GPU water. This might achieve a nice result of having water which moves naturally however also appears to be highly tessellated despite its low poly count.&lt;br /&gt;&lt;br /&gt;&lt;center&gt;&lt;object height="350" width="425"&gt;&lt;param name="movie" value="http://www.youtube.com/v/0oF09Vgp7MU"&gt;&lt;embed src="http://www.youtube.com/v/0oF09Vgp7MU" type="application/x-shockwave-flash" width="425" height="350"&gt;&lt;/embed&gt;&lt;/object&gt;&lt;/center&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2766425237491213801-2714910328903486633?l=decadeengine.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://decadeengine.blogspot.com/feeds/2714910328903486633/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://decadeengine.blogspot.com/2007/09/water-comparison.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2766425237491213801/posts/default/2714910328903486633'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2766425237491213801/posts/default/2714910328903486633'/><link rel='alternate' type='text/html' href='http://decadeengine.blogspot.com/2007/09/water-comparison.html' title='Water Comparison'/><author><name>Ciarán McCormack</name><uri>http://www.blogger.com/profile/12300242420318331807</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://3.bp.blogspot.com/_awzb2-vllx8/RvUoIT22uDI/AAAAAAAAAK4/xLVNybUCYB4/s72-c/CPU_Water_Comparison.JPG' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2766425237491213801.post-6566830373430575890</id><published>2007-09-21T23:29:00.000+01:00</published><updated>2007-09-22T15:33:21.708+01:00</updated><title type='text'>GPU Water</title><content type='html'>My second attempt at water rendering uses a vertex/pixel shader along with normal and dudv map's. Using the normal and dudv map's along with the reflection texture, which is dynamically generated each frame, the final effect is achieved.&lt;br /&gt;&lt;br /&gt;&lt;p align="left"&gt;&lt;a href="http://3.bp.blogspot.com/_awzb2-vllx8/RvUZ3T22t9I/AAAAAAAAAKI/cy5A2oYv6Po/s1600-h/normalmap.JPG"&gt;&lt;img id="BLOGGER_PHOTO_ID_5113021389962917842" style="DISPLAY: block; MARGIN: 0px auto 10px; WIDTH: 204px; CURSOR: hand; HEIGHT: 185px; TEXT-ALIGN: center" height="278" alt="" src="http://3.bp.blogspot.com/_awzb2-vllx8/RvUZ3T22t9I/AAAAAAAAAKI/cy5A2oYv6Po/s400/normalmap.JPG" width="204" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;The image above is the normal map. Instead of using each pixel for a color, the nomal map stores a normal (between -1 and 1). The normals naturally give the image a purple, pink and blue color. What we do with this image is basically use it to bump map our water to give it the appearance of being highly tessellated and realistic. This realism comes when we use per-pixel lighting on the water. If we didn't have a normal map we would just depend on the normal of the water surface, which is pointing straight up, the water would look like a flat mirror.&lt;br /&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;img id="BLOGGER_PHOTO_ID_5113021394257885154" style="DISPLAY: block; MARGIN: 0px auto 10px; WIDTH: 198px; CURSOR: hand; HEIGHT: 205px; TEXT-ALIGN: center" height="323" alt="" src="http://4.bp.blogspot.com/_awzb2-vllx8/RvUZ3j22t-I/AAAAAAAAAKQ/YX27iZf7Rx0/s400/dudvmap.JPG" width="291" border="0" /&gt;&lt;br /&gt;The image above is the dudv map. It is called that because it's actually the derivative of a normal map. In mathematics the notation for a derivative is du/dv. What this texture does is give us a way to calculate refraction and how the light will react and bend on the water. Notice how the dudv map looks like waves of water.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://1.bp.blogspot.com/_awzb2-vllx8/RvUfiz22uBI/AAAAAAAAAKo/wbnkXPJlN6s/s1600-h/reflection_texture.JPG"&gt;&lt;img id="BLOGGER_PHOTO_ID_5113027634845366290" style="DISPLAY: block; MARGIN: 0px auto 10px; WIDTH: 190px; CURSOR: hand; HEIGHT: 173px; TEXT-ALIGN: center" height="249" alt="" src="http://1.bp.blogspot.com/_awzb2-vllx8/RvUfiz22uBI/AAAAAAAAAKo/wbnkXPJlN6s/s400/reflection_texture.JPG" width="243" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;The image above is the reflection texture. This is caculated each frame by inverting the scene, setting up a clipping plane and rendering the reflective data. Projective texture mapping is then used to apply this texture to the water.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;a href="http://1.bp.blogspot.com/_awzb2-vllx8/RvUfiz22uCI/AAAAAAAAAKw/-a_SrZ43j_w/s1600-h/gpuwater.JPG"&gt;&lt;img id="BLOGGER_PHOTO_ID_5113027634845366306" style="DISPLAY: block; MARGIN: 0px auto 10px; CURSOR: hand; TEXT-ALIGN: center" alt="" src="http://1.bp.blogspot.com/_awzb2-vllx8/RvUfiz22uCI/AAAAAAAAAKw/-a_SrZ43j_w/s400/gpuwater.JPG" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;Although I am happy with this implementation there are a few changes that need to be made. Memories of my first implementation of CPU water are coming back. My lake again looks like a mirror. It is too bright and too reflective. It should be possible to see some way under the surface of the water.  I have tried to implement the simple changes which were required by CPU water, after I changed to using a reflection texture rather than drawing the inverted scene to the screen, however there is no differnce. Adding Alpha Blending with a fixed function does not seem to make any difference when the pixel shader is used. If I remove the shader from the rendering, a correct flat blue alpha blended quad is rendered. Since the GPU water is effected by per pixel lighting prehaps I need to modify the pixel shader in some way. I have read a few tutorials on OpenGL shaders, however I feel that I need to complete a few more before I have the confidence to say for sure.&lt;br /&gt;&lt;br /&gt;&lt;center&gt;&lt;object height="350" width="425"&gt;&lt;param name="movie" value="http://www.youtube.com/v/cXd39Af7Kyo"&gt;&lt;br /&gt;&lt;embed src="http://www.youtube.com/v/cXd39Af7Kyo" type="application/x-shockwave-flash" width="425" height="350"&gt;&lt;/embed&gt;&lt;/object&gt;&lt;/center&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2766425237491213801-6566830373430575890?l=decadeengine.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://decadeengine.blogspot.com/feeds/6566830373430575890/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://decadeengine.blogspot.com/2007/09/gpu-rendered-water.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2766425237491213801/posts/default/6566830373430575890'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2766425237491213801/posts/default/6566830373430575890'/><link rel='alternate' type='text/html' href='http://decadeengine.blogspot.com/2007/09/gpu-rendered-water.html' title='GPU Water'/><author><name>Ciarán McCormack</name><uri>http://www.blogger.com/profile/12300242420318331807</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://3.bp.blogspot.com/_awzb2-vllx8/RvUZ3T22t9I/AAAAAAAAAKI/cy5A2oYv6Po/s72-c/normalmap.JPG' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2766425237491213801.post-4230245400077755476</id><published>2007-09-19T06:39:00.000+01:00</published><updated>2007-09-22T15:03:04.744+01:00</updated><title type='text'>CPU Water</title><content type='html'>As all can see its been a while since I updated the blog so yesterday I recorded a small video of decade. You can now see the engine in motion rather than just static screenshots.&lt;br /&gt;&lt;br /&gt;Unfortunately YouTube has really lowered the quality of the video when it was uploaded but it should still give a rough idea about Decade.&lt;br /&gt;&lt;br /&gt;The video shows a simple terrain with random trees and my CPU water with vertex projected reflections.&lt;br /&gt;&lt;br /&gt;&lt;center&gt;&lt;object height="350" width="425"&gt;&lt;param name="movie" value="http://www.youtube.com/v/8pbN1HlByDY"&gt;&lt;param name="wmode" value="transparent"&gt;&lt;embed src="http://www.youtube.com/v/8pbN1HlByDY" type="application/x-shockwave-flash" wmode="transparent" width="425" height="350"&gt;&lt;/embed&gt;&lt;/object&gt;&lt;/center&gt;&lt;br /&gt;&lt;br /&gt;Other features that I am still working on are&lt;br /&gt;&lt;br /&gt;GPU Water&lt;br /&gt;Shadow Maps, Parallel Split Shadow Maps, Shadow Volumes&lt;br /&gt;Atmopheric Scattering&lt;br /&gt;Priority Rendering Queue&lt;br /&gt;Octree&lt;br /&gt;Scriptable Particle System&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2766425237491213801-4230245400077755476?l=decadeengine.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://decadeengine.blogspot.com/feeds/4230245400077755476/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://decadeengine.blogspot.com/2007/09/as-all-can-see-its-been-while-since-i.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2766425237491213801/posts/default/4230245400077755476'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2766425237491213801/posts/default/4230245400077755476'/><link rel='alternate' type='text/html' href='http://decadeengine.blogspot.com/2007/09/as-all-can-see-its-been-while-since-i.html' title='CPU Water'/><author><name>Ciarán McCormack</name><uri>http://www.blogger.com/profile/12300242420318331807</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2766425237491213801.post-8972961420510551527</id><published>2007-08-24T07:12:00.000+01:00</published><updated>2007-08-24T11:16:09.953+01:00</updated><title type='text'>Random Issues</title><content type='html'>Not a list of random issues, as the name suggests, but an issue with Random Number Generation. Both my procedural terrain generation techniques (Fault Formation and Midpoint Displacement) use &lt;span class="blsp-spelling-corrected" id="SPELLING_ERROR_0"&gt;pseudo random&lt;/span&gt; numbers. The other day when comparing Decade with Decade.NET it was quiet obvious that 2 very different terrains were built even though the same seed and procedural algorithms were used.&lt;br /&gt;&lt;br /&gt;Creating 2 basic programs, 1 in C++ and another in C#, I generated 10 random numbers using the seed '12345'. The C++ program generated "7584-19164-25795-22125-5828-23405-27477-5413-29072-23404" while the C# program generated "143337951-150666398-1663795458-1097663221-1912597933-1776631026-356393799-1580828476-558810388-1086637143". I then limited the C# number generation to be between 0 and RAND_MAX (32767) as the C++ rand() function does, but the results were still incorrect with "2187-2298-25386-46748-26131-27108-5437-24120-8526-16580" being generated.&lt;br /&gt;&lt;br /&gt;The easiest way to over come this has been to create a Managed C++ &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_1"&gt;DLL&lt;/span&gt; with members to seed and create random numbers. This &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_2"&gt;DLL&lt;/span&gt; is added as a reference to Decade.NET and it is used to get a random number rather than the Random object. Now both Decade and Decade.NET produce the same random numbers for a given seed any procedural work based on random numbers will match.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2766425237491213801-8972961420510551527?l=decadeengine.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://decadeengine.blogspot.com/feeds/8972961420510551527/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://decadeengine.blogspot.com/2007/08/random-issues.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2766425237491213801/posts/default/8972961420510551527'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2766425237491213801/posts/default/8972961420510551527'/><link rel='alternate' type='text/html' href='http://decadeengine.blogspot.com/2007/08/random-issues.html' title='Random Issues'/><author><name>Ciarán McCormack</name><uri>http://www.blogger.com/profile/12300242420318331807</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2766425237491213801.post-4109364155219117153</id><published>2007-08-20T19:15:00.001+01:00</published><updated>2007-08-21T07:26:16.833+01:00</updated><title type='text'>Resistance is Futile</title><content type='html'>&lt;p&gt;It may not be futile, but it is very difficult to resist coding new features when some maintenance needs to be done on what has already been developed. The desire to implement the next big thing is tempting. However I have thus far succeeded in doing what I believe needs to be done in order to improve decade as it exists already.&lt;br /&gt;&lt;br /&gt;Friends have told me that premature optimizations are the death of many projects; however I don’t feel that what I am doing now is really optimising. This has always been a learning project, not exactly made up as I went along, but that does have an element of truth. It was best implemented at the time based on what I knew, and through experience learned from my implementation, experimenting and reading I now see there are better and faster ways to do things. Further developments also rely on these better ways of doing the basic things therefore it is important that they are implemented now. e.g. Water will rely on &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_0"&gt;geomipmapped&lt;/span&gt; terrain to&lt;br /&gt;&lt;br /&gt;A) Reduce the Number of water polygons rendered and&lt;br /&gt;B) Reduce the number of water &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_1"&gt;vertices&lt;/span&gt; updated and projected to screen&lt;br /&gt;&lt;br /&gt;Improvements made this week are....&lt;br /&gt;&lt;br /&gt;&lt;em&gt;&lt;strong&gt;Use triangle strips rather than triangle lists when rendering Terrain/Water patches.&lt;/strong&gt;&lt;/em&gt;&lt;br /&gt;I have been told in a forum that the more information passed to the &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_2"&gt;GC&lt;/span&gt; (Graphics Card) the faster it can render so therefore triangle lists are the best for performance. I cannot find any information to back this up so I will test for myself, but I find it difficult to believe that this is true. Consider the amount of information that needs to be passed each frame....&lt;br /&gt;&lt;br /&gt;Patch Size = 17&lt;br /&gt;Triangle List would have 1734 Indices for Patch of highest &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_3"&gt;LOD&lt;/span&gt;&lt;br /&gt;Triangle Strip would have 644 Indices for Patch of highest &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_4"&gt;LOD&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;and presume there are 1000 patches rendered a frame (in a 1024*1024 terrain there would be 3721 Patches) there is a huge difference in the amount of index data sent to the &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_5"&gt;GC&lt;/span&gt;. 1764000 as opposed to 644000. Decade supports lists and strips for terrain patch rendering so I will at some stage benchmark the performance of both.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;em&gt;&lt;strong&gt;Remove Terrain Cracks.&lt;/strong&gt;&lt;br /&gt;&lt;/em&gt;In terrains which support Level of Details (&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_6"&gt;LOD&lt;/span&gt;) &lt;span class="blsp-spelling-corrected" id="SPELLING_ERROR_7"&gt;artefact's&lt;/span&gt; called cracks can appear. These can caused when a terrain patch has another terrain patch with a lower &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_8"&gt;LOD&lt;/span&gt; as its neighbour. In the image below you can see the cracks in the distance. I have removed the &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_9"&gt;skybox&lt;/span&gt; because the black background highlights the cracks.&lt;/p&gt;&lt;a href="http://1.bp.blogspot.com/_awzb2-vllx8/Rsnad92u5cI/AAAAAAAAAJw/lPI7hsa6DQE/s1600-h/cracks.JPG"&gt;&lt;img id="BLOGGER_PHOTO_ID_5100848261328987586" style="DISPLAY: block; MARGIN: 0px auto 10px; CURSOR: hand; TEXT-ALIGN: center" alt="" src="http://1.bp.blogspot.com/_awzb2-vllx8/Rsnad92u5cI/AAAAAAAAAJw/lPI7hsa6DQE/s400/cracks.JPG" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;Below you can see an up-close image of the cracks. In reality it would not be possible to see a crack this close because as stated it is when a patch neighbours a patch with lower &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_10"&gt;LOD&lt;/span&gt;, and that will always occur in the distance. The wire frame image should make it more apparent why these &lt;span class="blsp-spelling-corrected" id="SPELLING_ERROR_11"&gt;artefact's&lt;/span&gt; occur.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;&lt;a href="http://2.bp.blogspot.com/_awzb2-vllx8/RsnaeN2u5dI/AAAAAAAAAJ4/E1s44daQfu0/s1600-h/cracks_details.JPG"&gt;&lt;img id="BLOGGER_PHOTO_ID_5100848265623954898" style="DISPLAY: block; MARGIN: 0px auto 10px; CURSOR: hand; TEXT-ALIGN: center" alt="" src="http://2.bp.blogspot.com/_awzb2-vllx8/RsnaeN2u5dI/AAAAAAAAAJ4/E1s44daQfu0/s400/cracks_details.JPG" border="0" /&gt;&lt;/a&gt; &lt;/p&gt;&lt;p&gt;There are 2 methods to remove the crack. The 1st is "Vertex Insertion" into the patch with the lower &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_12"&gt;LOD&lt;/span&gt;. This is not a difficult task; however it is the more complex of the 2 methods so we will ignore it. The 2&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_13"&gt;nd&lt;/span&gt; and preferred method is "Vertex Removal" from the patch with the higher &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_14"&gt;LOD&lt;/span&gt;. Decade presumes that a patch can only neighbour a patch with an &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_15"&gt;LOD&lt;/span&gt; that is the same as its own, or has a difference of 1. (i.e. 1 Level Greater than or less than its own). With this being the case, to remove a vertex from a patch we simply navigate the index buffer to the indices relating to the side of the patch in the direction of its neighbour (North, South, East or West) and remove every 2&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_16"&gt;nd&lt;/span&gt; index. And to make it even more simple, we don’t even have to "remove" the index. By setting the index equal to the next index in the array we visually remove the vertex from the patch, however it is still theoretically present, but rendered as a degenerate triangle (a triangle which has 2 &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_17"&gt;vertices&lt;/span&gt; the same, hence no area) and apparently &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_18"&gt;OpenGL&lt;/span&gt; and &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_19"&gt;DX&lt;/span&gt; can recognise degenerate triangles and do not even send them to the &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_20"&gt;GC&lt;/span&gt;.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;a href="http://2.bp.blogspot.com/_awzb2-vllx8/RsnaeN2u5eI/AAAAAAAAAKA/RpVYEy4S5kI/s1600-h/fixed_cracks_details.JPG"&gt;&lt;img id="BLOGGER_PHOTO_ID_5100848265623954914" style="DISPLAY: block; MARGIN: 0px auto 10px; CURSOR: hand; TEXT-ALIGN: center" alt="" src="http://2.bp.blogspot.com/_awzb2-vllx8/RsnaeN2u5eI/AAAAAAAAAKA/RpVYEy4S5kI/s400/fixed_cracks_details.JPG" border="0" /&gt;&lt;/a&gt; &lt;/p&gt;&lt;p&gt;To further improve the speed of Decade, all this is &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_21"&gt;pre&lt;/span&gt;-calculated. For every &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_22"&gt;LOD&lt;/span&gt; which the terrain supports 16 index buffers are created.&lt;br /&gt;&lt;br /&gt;00 None Lower&lt;br /&gt;01 West Lower&lt;br /&gt;02 East Lower&lt;br /&gt;03 East-West Lower&lt;br /&gt;04 South Lower&lt;br /&gt;05 South-West Lower&lt;br /&gt;06 South-East Lower&lt;br /&gt;07 South-East-West Lower&lt;br /&gt;08 North Lower&lt;br /&gt;09 North-West Lower&lt;br /&gt;10 North-East Lower&lt;br /&gt;11 North-East-West Lower&lt;br /&gt;12 North-South Lower&lt;br /&gt;13 North-South-West Lower&lt;br /&gt;14 North-South-East Lower&lt;br /&gt;15 North-South-East-West Lower&lt;br /&gt;&lt;br /&gt;and during &lt;span class="blsp-spelling-corrected" id="SPELLING_ERROR_23"&gt;run time&lt;/span&gt; the correct index buffer is selected and applied to the associated vertex buffer. Many tutorials I have seen update the index information at run-time however I think this is unreasonable for high performance in a large terrain. In Decade a Nibble (Half a Byte) is used in order to select the required index buffer.&lt;br /&gt;&lt;br /&gt;1000 = North Patch is Lower &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_24"&gt;LOD&lt;/span&gt;&lt;br /&gt;0100 = South Patch is Lower &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_25"&gt;LOD&lt;/span&gt;&lt;br /&gt;0010 = East Patch is Lower &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_26"&gt;LOD&lt;/span&gt;&lt;br /&gt;0001 = West Patch is Lower &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_27"&gt;LOD&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;So the pseudo code for selecting the correct index buffer to use would be&lt;br /&gt;&lt;br /&gt;byte &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_28"&gt;IndexBuffer&lt;/span&gt; = 0x00;&lt;br /&gt;if North Neighbour's &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_29"&gt;LOD&lt;/span&gt; LessThan This Patch's LOD&lt;br /&gt;&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_31"&gt;IndexBuffer&lt;/span&gt; = &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_32"&gt;IndexBuffer&lt;/span&gt; XOR 8 (1000 in Binary)&lt;br /&gt;if South Neighbour's &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_33"&gt;LOD&lt;/span&gt; LessThan This Patch's LOD&lt;br /&gt;&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_35"&gt;IndexBuffer&lt;/span&gt; = &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_36"&gt;IndexBuffer&lt;/span&gt; XOR 4 (0100 in Binary)&lt;br /&gt;if East Neighbour's &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_37"&gt;LOD&lt;/span&gt; LessThan This Patch's LOD&lt;/span&gt;&lt;br /&gt;&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_39"&gt;IndexBuffer&lt;/span&gt; = &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_40"&gt;IndexBuffer&lt;/span&gt; XOR 2 (0010 in Binary)&lt;br /&gt;if West Neighbour's &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_41"&gt;LOD&lt;/span&gt; LessThan This Patch's LOD&lt;/span&gt;&lt;br /&gt;&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_43"&gt;IndexBuffer&lt;/span&gt; = &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_44"&gt;IndexBuffer&lt;/span&gt; XOR 1 (0001 in Binary)&lt;br /&gt;&lt;br /&gt;For example presume that we had a Patch which had the following Neighbours. North and West = Same &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_45"&gt;LOD&lt;/span&gt; as the Patch, South and East has a Lower &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_46"&gt;LOD&lt;/span&gt;. Running through the above code we would hit the lines&lt;br /&gt;&lt;br /&gt;&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_47"&gt;IndexBuffer&lt;/span&gt; = 0x00;&lt;br /&gt;&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_48"&gt;IndexBuffer&lt;/span&gt; = &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_49"&gt;IndexBuffer&lt;/span&gt; XOR 4&lt;br /&gt;&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_50"&gt;IndexBuffer&lt;/span&gt; = &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_51"&gt;IndexBuffer&lt;/span&gt; XOR 2&lt;br /&gt;&lt;br /&gt;which gives us &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_52"&gt;IndexBuffer&lt;/span&gt; of 0110 or 6. Referencing the above array we see that index 6 provides the Index Buffer for a Patch with South and East having lower &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_53"&gt;LOD's&lt;/span&gt; which is exactly what we required.&lt;/p&gt;&lt;p&gt;This has been my first attempt to make my posts a &lt;span class="blsp-spelling-corrected" id="SPELLING_ERROR_54"&gt;Little&lt;/span&gt; more technical. I hope I succeeded in explaining how I was achieving certain behaviour in Decade. I would be delighted to hear your questions or comments.&lt;br /&gt;&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2766425237491213801-4109364155219117153?l=decadeengine.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://decadeengine.blogspot.com/feeds/4109364155219117153/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://decadeengine.blogspot.com/2007/08/resistance-is-futile.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2766425237491213801/posts/default/4109364155219117153'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2766425237491213801/posts/default/4109364155219117153'/><link rel='alternate' type='text/html' href='http://decadeengine.blogspot.com/2007/08/resistance-is-futile.html' title='Resistance is Futile'/><author><name>Ciarán McCormack</name><uri>http://www.blogger.com/profile/12300242420318331807</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://1.bp.blogspot.com/_awzb2-vllx8/Rsnad92u5cI/AAAAAAAAAJw/lPI7hsa6DQE/s72-c/cracks.JPG' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2766425237491213801.post-8323563682786525219</id><published>2007-08-09T18:34:00.000+01:00</published><updated>2007-08-16T09:24:47.600+01:00</updated><title type='text'>Vertex Projected Reflections</title><content type='html'>A new implementation was required in order to achieve better looking software water. It is slightly more complicated, a little more CPU expensive but I feel the results are allot more appealing and worth it. No hardware acceleration was used so this should hopefully work on any computer.&lt;br /&gt;&lt;br /&gt;The differences are:&lt;br /&gt;&lt;br /&gt;Previous&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Invert the scene so that it is upside down&lt;/li&gt;&lt;li&gt;Setup the clipping plane so that only vertices above the water (those that will be reflected) are drawn&lt;/li&gt;&lt;li&gt;Draw the scene&lt;/li&gt;&lt;li&gt;Disable the clipping plane&lt;/li&gt;&lt;li&gt;Render scene as normal&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;Now&lt;/p&gt;&lt;ul&gt;&lt;li&gt;Invert the scene so that it is upside down&lt;/li&gt;&lt;li&gt;Setup the clipping plane so that only vertices above the water (those that will be reflected) are drawn&lt;/li&gt;&lt;li&gt;Render the scene to a texture to be used when rendering the water&lt;/li&gt;&lt;li&gt;Project each of the water vertices to screen coordinates. Set these values as water texture coordinates&lt;/li&gt;&lt;li&gt;Render scene as normal&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;&lt;a href="http://1.bp.blogspot.com/_awzb2-vllx8/RrtQwCZHPWI/AAAAAAAAAJg/pVAGiocfowA/s1600-h/sun.JPG"&gt;&lt;img id="BLOGGER_PHOTO_ID_5096756189505994082" style="DISPLAY: block; MARGIN: 0px auto 10px; CURSOR: hand; TEXT-ALIGN: center" alt="" src="http://1.bp.blogspot.com/_awzb2-vllx8/RrtQwCZHPWI/AAAAAAAAAJg/pVAGiocfowA/s400/sun.JPG" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;Further optimizations are to be added for the water. Use a terrain approach to render the water by splitting it into patches and rendering with a level of detail therefore reducing the polygons drawn in the distance. As well as reducing the number of polygons rendered I should be able equally cut the number of water vertices updated and projected to screen.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href="http://2.bp.blogspot.com/_awzb2-vllx8/RrtQwSZHPXI/AAAAAAAAAJo/A8OVfex9rrA/s1600-h/Panorama+1.JPG"&gt;&lt;img id="BLOGGER_PHOTO_ID_5096756193800961394" style="DISPLAY: block; MARGIN: 0px auto 10px; CURSOR: hand; TEXT-ALIGN: center" alt="" src="http://2.bp.blogspot.com/_awzb2-vllx8/RrtQwSZHPXI/AAAAAAAAAJo/A8OVfex9rrA/s400/Panorama+1.JPG" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;p&gt;I have just looked through this blog and feel a little dubious about it. I guess the first question is does anyone read it? If so can you let me know. I am going to update it as often as required regardless because it is a nice timeline of the Decade Engine for me, however if people read it and would like to learn something from it please let me know. I can start to make the posts more technical with sample source, comparisons etc... In essence start to build up a 3D engine tutorial.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2766425237491213801-8323563682786525219?l=decadeengine.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://decadeengine.blogspot.com/feeds/8323563682786525219/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://decadeengine.blogspot.com/2007/08/vertex-projected-reflections.html#comment-form' title='4 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2766425237491213801/posts/default/8323563682786525219'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2766425237491213801/posts/default/8323563682786525219'/><link rel='alternate' type='text/html' href='http://decadeengine.blogspot.com/2007/08/vertex-projected-reflections.html' title='Vertex Projected Reflections'/><author><name>Ciarán McCormack</name><uri>http://www.blogger.com/profile/12300242420318331807</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://1.bp.blogspot.com/_awzb2-vllx8/RrtQwCZHPWI/AAAAAAAAAJg/pVAGiocfowA/s72-c/sun.JPG' height='72' width='72'/><thr:total>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2766425237491213801.post-8072513100122408786</id><published>2007-08-05T19:55:00.000+01:00</published><updated>2007-08-16T09:25:24.956+01:00</updated><title type='text'>Reflections</title><content type='html'>I find it hard to believe that its been almost a month since I last posted. I guess there just hasn't been much new to show since then, as I was converting Decade to Decade.NET. Progress is slow due to a busy life but its now almost there.&lt;br /&gt;&lt;br /&gt;Today, for a change (which they say is as good as a break) I decided to implement reflections. A second render pass was needed. 1 to draw a clipped upside down scene which is used for the reflection and then the normal scene.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href="http://1.bp.blogspot.com/_awzb2-vllx8/RrYdVSZHPUI/AAAAAAAAAJQ/87w_R3yLMn4/s1600-h/reflections_1.JPG"&gt;&lt;img id="BLOGGER_PHOTO_ID_5095292279967923522" style="DISPLAY: block; MARGIN: 0px auto 10px; CURSOR: hand; TEXT-ALIGN: center" alt="" src="http://1.bp.blogspot.com/_awzb2-vllx8/RrYdVSZHPUI/AAAAAAAAAJQ/87w_R3yLMn4/s400/reflections_1.JPG" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;Unfortunately these images as usual do not do Decade justice. The water looks like a sheet of glass, however in Real Time with the water moving and light reflecting realism is better. I think I will finish software water soon and then add DUDV maps for hardware rendered water.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href="http://2.bp.blogspot.com/_awzb2-vllx8/RrYdViZHPVI/AAAAAAAAAJY/1tRaLy0fWBc/s1600-h/reflections_2.JPG"&gt;&lt;img id="BLOGGER_PHOTO_ID_5095292284262890834" style="DISPLAY: block; MARGIN: 0px auto 10px; CURSOR: hand; TEXT-ALIGN: center" alt="" src="http://2.bp.blogspot.com/_awzb2-vllx8/RrYdViZHPVI/AAAAAAAAAJY/1tRaLy0fWBc/s400/reflections_2.JPG" border="0" /&gt;&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2766425237491213801-8072513100122408786?l=decadeengine.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://decadeengine.blogspot.com/feeds/8072513100122408786/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://decadeengine.blogspot.com/2007/08/i-find-it-hard-to-believe-that-its-been.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2766425237491213801/posts/default/8072513100122408786'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2766425237491213801/posts/default/8072513100122408786'/><link rel='alternate' type='text/html' href='http://decadeengine.blogspot.com/2007/08/i-find-it-hard-to-believe-that-its-been.html' title='Reflections'/><author><name>Ciarán McCormack</name><uri>http://www.blogger.com/profile/12300242420318331807</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://1.bp.blogspot.com/_awzb2-vllx8/RrYdVSZHPUI/AAAAAAAAAJQ/87w_R3yLMn4/s72-c/reflections_1.JPG' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2766425237491213801.post-5931816520499685383</id><published>2007-07-06T07:40:00.000+01:00</published><updated>2007-07-06T07:47:31.910+01:00</updated><title type='text'>C++ to C#</title><content type='html'>I have written many programs in C++ and many in C# before but this is the first time I have tried to convert a full C++ program in C#. Since both languages have a very similar structure and share allot in common I thought this would be a simple matter but I was very wrong.&lt;br /&gt;&lt;br /&gt;Its by no means an impossible task, however the small but significant differences require some rethinking and restructuring of Decade. (Managed Code, stronger typecasting, delegates etc...) I have allot of the core graphics components complete and am now on the File Parsers. It has taken a short while to get a grasp of Regex instead of using sscanf and such functions, but now progress is moving again. Hopefully by next week I will have some screenshots from Decade.NET.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2766425237491213801-5931816520499685383?l=decadeengine.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://decadeengine.blogspot.com/feeds/5931816520499685383/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://decadeengine.blogspot.com/2007/07/c-to-c.html#comment-form' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2766425237491213801/posts/default/5931816520499685383'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2766425237491213801/posts/default/5931816520499685383'/><link rel='alternate' type='text/html' href='http://decadeengine.blogspot.com/2007/07/c-to-c.html' title='C++ to C#'/><author><name>Ciarán McCormack</name><uri>http://www.blogger.com/profile/12300242420318331807</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2766425237491213801.post-3909744130025699070</id><published>2007-07-01T17:38:00.000+01:00</published><updated>2007-07-01T17:44:33.300+01:00</updated><title type='text'>Panorama</title><content type='html'>As conversion continues, and there &lt;span class="blsp-spelling-corrected" id="SPELLING_ERROR_0"&gt;isn't&lt;/span&gt; really anything new to show, I thought I would upload these these test images. They show randomly generated scenes in Decade (hence why there are trees growing in the water) in &lt;span class="blsp-spelling-corrected" id="SPELLING_ERROR_1"&gt;panorama&lt;/span&gt; form,&lt;br /&gt;&lt;br /&gt;&lt;a href="http://4.bp.blogspot.com/_awzb2-vllx8/RofYvj389pI/AAAAAAAAAI4/ewF1Enmva8Q/s1600-h/Panorama+15.JPG"&gt;&lt;img id="BLOGGER_PHOTO_ID_5082269016106268306" style="DISPLAY: block; MARGIN: 0px auto 10px; CURSOR: hand; TEXT-ALIGN: center" alt="" src="http://4.bp.blogspot.com/_awzb2-vllx8/RofYvj389pI/AAAAAAAAAI4/ewF1Enmva8Q/s400/Panorama+15.JPG" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;a href="http://1.bp.blogspot.com/_awzb2-vllx8/RofYvz389qI/AAAAAAAAAJA/RSU9izKmrLg/s1600-h/Panorama+16.JPG"&gt;&lt;img id="BLOGGER_PHOTO_ID_5082269020401235618" style="DISPLAY: block; MARGIN: 0px auto 10px; CURSOR: hand; TEXT-ALIGN: center" alt="" src="http://1.bp.blogspot.com/_awzb2-vllx8/RofYvz389qI/AAAAAAAAAJA/RSU9izKmrLg/s400/Panorama+16.JPG" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;a href="http://1.bp.blogspot.com/_awzb2-vllx8/RofYvz389rI/AAAAAAAAAJI/uIRD9aIG-Tg/s1600-h/Panorama+17.JPG"&gt;&lt;img id="BLOGGER_PHOTO_ID_5082269020401235634" style="DISPLAY: block; MARGIN: 0px auto 10px; CURSOR: hand; TEXT-ALIGN: center" alt="" src="http://1.bp.blogspot.com/_awzb2-vllx8/RofYvz389rI/AAAAAAAAAJI/uIRD9aIG-Tg/s400/Panorama+17.JPG" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;div&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2766425237491213801-3909744130025699070?l=decadeengine.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://decadeengine.blogspot.com/feeds/3909744130025699070/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://decadeengine.blogspot.com/2007/07/panorama.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2766425237491213801/posts/default/3909744130025699070'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2766425237491213801/posts/default/3909744130025699070'/><link rel='alternate' type='text/html' href='http://decadeengine.blogspot.com/2007/07/panorama.html' title='Panorama'/><author><name>Ciarán McCormack</name><uri>http://www.blogger.com/profile/12300242420318331807</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://4.bp.blogspot.com/_awzb2-vllx8/RofYvj389pI/AAAAAAAAAI4/ewF1Enmva8Q/s72-c/Panorama+15.JPG' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2766425237491213801.post-3707421277167412842</id><published>2007-06-26T22:34:00.000+01:00</published><updated>2007-07-02T16:59:50.702+01:00</updated><title type='text'>June is almost over already!</title><content type='html'>July has been a quiet month with posts, however development continues. Holidays. Being busy at work. Having custom work to complete outside work etc.... the month has just disappeared.&lt;br /&gt;&lt;br /&gt;Deciding that my own custom GUI components &lt;span class="blsp-spelling-corrected" id="SPELLING_ERROR_0"&gt;wasn't&lt;/span&gt; the best way to spend my time, I started development on Decade in C# using Tao for &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_1"&gt;OpenGL&lt;/span&gt;. Development is slow but steady. I am currently adding in the file parsers for the 3D file formats and then terrain loaders/generators. With this complete it will be on par with Decade and I can begin working on my Sandbox Editors.&lt;br /&gt;&lt;br /&gt;There are no screenshots to show, because I am using the same media as Decade and the screenshots look identical. Hopefully I will get some more spare time soon and can get the rest of the current in development work completed.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2766425237491213801-3707421277167412842?l=decadeengine.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://decadeengine.blogspot.com/feeds/3707421277167412842/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://decadeengine.blogspot.com/2007/06/decadenet.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2766425237491213801/posts/default/3707421277167412842'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2766425237491213801/posts/default/3707421277167412842'/><link rel='alternate' type='text/html' href='http://decadeengine.blogspot.com/2007/06/decadenet.html' title='June is almost over already!'/><author><name>Ciarán McCormack</name><uri>http://www.blogger.com/profile/12300242420318331807</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2766425237491213801.post-4676446968187873560</id><published>2007-06-07T13:40:00.000+01:00</published><updated>2007-06-07T13:48:43.883+01:00</updated><title type='text'>Decade .NET</title><content type='html'>For the past number of days I have been &lt;span class="blsp-spelling-corrected" id="SPELLING_ERROR_0"&gt;contemplating&lt;/span&gt; moving Decade to .NET. Programming the GUI Interface has raised this issue. I am currently spending &lt;span class="blsp-spelling-corrected" id="SPELLING_ERROR_1"&gt;allot&lt;/span&gt; of time programming a GUI System so that I can make Level Editors and a range of other tools for Decade.&lt;br /&gt;&lt;br /&gt;Drawing and managing the controls myself was inspired by Unreal Tournament, however my results are nothing like this. I &lt;span class="blsp-spelling-corrected" id="SPELLING_ERROR_2"&gt;don't&lt;/span&gt; have the artwork or the time to match these results. In truth my rendered buttons do not look much different to those I created almost 10 years ago when making simple Mode13h Dos Games. In short, with this method I am spending &lt;span class="blsp-spelling-corrected" id="SPELLING_ERROR_3"&gt;allot&lt;/span&gt; of time with little gain and not really learning anything.&lt;br /&gt;&lt;br /&gt;Another possibility would be to make the GUI in WIN32, therefore keep the engine as C++. This would save time in now requiring me to rewrite the engine, however I find GUI work in WIN32 to be &lt;span class="blsp-spelling-corrected" id="SPELLING_ERROR_4"&gt;hideous&lt;/span&gt;.&lt;br /&gt;&lt;br /&gt;Although requiring the most work and the most time, I think that converting Decade to C# is the best course of action. With this I get to refresh my C#, learn some more .NET and have a nice and simple way to create good &lt;span class="blsp-spelling-corrected" id="SPELLING_ERROR_5"&gt;Gui's&lt;/span&gt; for my tools. To help me with this I have found &lt;a href="http://www.taoframework.com/"&gt;The Tao Framework.&lt;/a&gt; This will help &lt;span class="blsp-spelling-corrected" id="SPELLING_ERROR_6"&gt;allot&lt;/span&gt; in using &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_7"&gt;OpenGL&lt;/span&gt; with C#.&lt;br /&gt;&lt;br /&gt;If anyone has any comments or ideas on this plan I would like to hear them.&lt;br /&gt;&lt;br /&gt;Thanks&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2766425237491213801-4676446968187873560?l=decadeengine.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://decadeengine.blogspot.com/feeds/4676446968187873560/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://decadeengine.blogspot.com/2007/06/decade-net.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2766425237491213801/posts/default/4676446968187873560'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2766425237491213801/posts/default/4676446968187873560'/><link rel='alternate' type='text/html' href='http://decadeengine.blogspot.com/2007/06/decade-net.html' title='Decade .NET'/><author><name>Ciarán McCormack</name><uri>http://www.blogger.com/profile/12300242420318331807</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2766425237491213801.post-3165456902614405860</id><published>2007-06-04T13:52:00.000+01:00</published><updated>2007-06-04T13:55:13.082+01:00</updated><title type='text'>Update</title><content type='html'>Decade Engine is still alive. It has been about 10 days since I worked on it. Last week I had holidays and I also got a new acoustic guitar so was distracted from programming for a short while. In the few hours that I did work on the engine focus was on making GUI Components and the GUI Manager. I hope that buttons, combo boxes, list boxes, edit boxes etc... will all be supported soon and I can start work on mesh and level editors.&lt;br /&gt;&lt;br /&gt;Hopefully I will have some screenshots soon, but so far development in this area has been allot of functional stuff so nothing nice to show.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2766425237491213801-3165456902614405860?l=decadeengine.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://decadeengine.blogspot.com/feeds/3165456902614405860/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://decadeengine.blogspot.com/2007/06/update.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2766425237491213801/posts/default/3165456902614405860'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2766425237491213801/posts/default/3165456902614405860'/><link rel='alternate' type='text/html' href='http://decadeengine.blogspot.com/2007/06/update.html' title='Update'/><author><name>Ciarán McCormack</name><uri>http://www.blogger.com/profile/12300242420318331807</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2766425237491213801.post-5658419710383101249</id><published>2007-05-23T21:10:00.000+01:00</published><updated>2007-05-29T22:46:29.028+01:00</updated><title type='text'>Let there be Light</title><content type='html'>Basic lighting has been added to Decade. This adds another slight layer of realism to the scene. In my opinion the screenshot below does not do Decade Justice. The moving water being effected by light and shade creates an impressive effect. I have tried to create a video to upload to &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_0"&gt;YouTube&lt;/span&gt; so I can show here but so far the quality &lt;span class="blsp-spelling-corrected" id="SPELLING_ERROR_1"&gt;hasn't&lt;/span&gt; been worth showing.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://2.bp.blogspot.com/_awzb2-vllx8/RlSf4ZU6OtI/AAAAAAAAAIw/VXCVFX4C4yM/s1600-h/water_lights_23-05-07.JPG"&gt;&lt;img id="BLOGGER_PHOTO_ID_5067851271918729938" style="DISPLAY: block; MARGIN: 0px auto 10px; CURSOR: hand; TEXT-ALIGN: center" alt="" src="http://2.bp.blogspot.com/_awzb2-vllx8/RlSf4ZU6OtI/AAAAAAAAAIw/VXCVFX4C4yM/s400/water_lights_23-05-07.JPG" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;div&gt;Patch Culling and &lt;span class="blsp-spelling-corrected" id="SPELLING_ERROR_2"&gt;Node Tree&lt;/span&gt; has been added to Brute Force Terrain. This now exceeds the frame rate of software rendered &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_3"&gt;Geomipmapping&lt;/span&gt;, however &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_4"&gt;Geomipping&lt;/span&gt; will soon be Hardware Rendered too and will hopefully increase in frame rate.&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;Other in progress work are &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_5"&gt;Scriptable&lt;/span&gt; Particle Systems and GUI Components such as buttons, combo boxes etc...&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2766425237491213801-5658419710383101249?l=decadeengine.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://decadeengine.blogspot.com/feeds/5658419710383101249/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://decadeengine.blogspot.com/2007/05/let-there-be-light.html#comment-form' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2766425237491213801/posts/default/5658419710383101249'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2766425237491213801/posts/default/5658419710383101249'/><link rel='alternate' type='text/html' href='http://decadeengine.blogspot.com/2007/05/let-there-be-light.html' title='Let there be Light'/><author><name>Ciarán McCormack</name><uri>http://www.blogger.com/profile/12300242420318331807</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://2.bp.blogspot.com/_awzb2-vllx8/RlSf4ZU6OtI/AAAAAAAAAIw/VXCVFX4C4yM/s72-c/water_lights_23-05-07.JPG' height='72' width='72'/><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2766425237491213801.post-8892102496656859745</id><published>2007-05-18T19:11:00.003+01:00</published><updated>2007-05-29T22:47:45.104+01:00</updated><title type='text'>Software Water</title><content type='html'>Although I hope that some day Decade is a high end 3D engine supporting the most advanced technologies and rendering techniques, at present I want to make sure that almost anyone can play my games.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://3.bp.blogspot.com/_awzb2-vllx8/Rk4dKJU6OqI/AAAAAAAAAIY/jGSgO8TTbDQ/s1600-h/software_water-18-05-07.JPG"&gt;&lt;img id="BLOGGER_PHOTO_ID_5066018690977905314" style="DISPLAY: block; MARGIN: 0px auto 10px; CURSOR: hand; TEXT-ALIGN: center" alt="" src="http://3.bp.blogspot.com/_awzb2-vllx8/Rk4dKJU6OqI/AAAAAAAAAIY/jGSgO8TTbDQ/s400/software_water-18-05-07.JPG" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;My full blown water will be rendered using Bump Maps and Stencil Reflections, which not all Graphics Cards support therefore I have first implemented a simple alpha blended tessellating mesh with a sphere mapped texture. Results are not very realistic however give the impression of water with semi-realistic movement.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://3.bp.blogspot.com/_awzb2-vllx8/Rk4dKJU6OrI/AAAAAAAAAIg/OjlT16VUvqM/s1600-h/software_water2-18-05-07.JPG"&gt;&lt;img id="BLOGGER_PHOTO_ID_5066018690977905330" style="DISPLAY: block; MARGIN: 0px auto 10px; CURSOR: hand; TEXT-ALIGN: center" alt="" src="http://3.bp.blogspot.com/_awzb2-vllx8/Rk4dKJU6OrI/AAAAAAAAAIg/OjlT16VUvqM/s400/software_water2-18-05-07.JPG" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;In &lt;span class="blsp-spelling-corrected" id="SPELLING_ERROR_0"&gt;Wire frame&lt;/span&gt; one can see the mesh clearly. As the water mesh is constantly moving and is alpha blended it does not have to be as high a resolution as the terrain. The terrain is the images shown is 512x512 whereas the water mesh is only 60x60.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://4.bp.blogspot.com/_awzb2-vllx8/Rk4dKZU6OsI/AAAAAAAAAIo/9JpYjx0oQ7s/s1600-h/software_water3-18-05-07.JPG"&gt;&lt;img id="BLOGGER_PHOTO_ID_5066018695272872642" style="DISPLAY: block; MARGIN: 0px auto 10px; CURSOR: hand; TEXT-ALIGN: center" alt="" src="http://4.bp.blogspot.com/_awzb2-vllx8/Rk4dKZU6OsI/AAAAAAAAAIo/9JpYjx0oQ7s/s400/software_water3-18-05-07.JPG" border="0" /&gt;&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2766425237491213801-8892102496656859745?l=decadeengine.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://decadeengine.blogspot.com/feeds/8892102496656859745/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://decadeengine.blogspot.com/2007/05/software-water.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2766425237491213801/posts/default/8892102496656859745'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2766425237491213801/posts/default/8892102496656859745'/><link rel='alternate' type='text/html' href='http://decadeengine.blogspot.com/2007/05/software-water.html' title='Software Water'/><author><name>Ciarán McCormack</name><uri>http://www.blogger.com/profile/12300242420318331807</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://3.bp.blogspot.com/_awzb2-vllx8/Rk4dKJU6OqI/AAAAAAAAAIY/jGSgO8TTbDQ/s72-c/software_water-18-05-07.JPG' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2766425237491213801.post-3415191714919052330</id><published>2007-05-16T07:30:00.000+01:00</published><updated>2007-05-29T22:48:19.301+01:00</updated><title type='text'>Multiple View Ports</title><content type='html'>To take a little break from terrain programming I decided to try something else last night. While watching a Formula 1 Grand &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_0"&gt;Prix&lt;/span&gt; over the weekend it reminded me of playing racing games and being able to turn on or off the rear view. Having always wanted to implement this I decided that now was the time.&lt;br /&gt;&lt;br /&gt;I was amazed at how easy it is in &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_1"&gt;OpenGL&lt;/span&gt; to &lt;span class="blsp-spelling-corrected" id="SPELLING_ERROR_2"&gt;achieve&lt;/span&gt; multiple view ports. After 10 minutes of reading an online document I realised that I already had all the code from my &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_3"&gt;OpenGL&lt;/span&gt; setup functions so only a little reorganisation was required.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://1.bp.blogspot.com/_awzb2-vllx8/Rkrs3pU6OiI/AAAAAAAAAHY/JL48pN3pmeA/s1600-h/multiple_viewports_2_16-05-07.JPG"&gt;&lt;img id="BLOGGER_PHOTO_ID_5065121171662060066" style="DISPLAY: block; MARGIN: 0px auto 10px; CURSOR: hand; TEXT-ALIGN: center" alt="" src="http://1.bp.blogspot.com/_awzb2-vllx8/Rkrs3pU6OiI/AAAAAAAAAHY/JL48pN3pmeA/s400/multiple_viewports_2_16-05-07.JPG" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;Decade can now support 1 t0 X &lt;span class="blsp-spelling-corrected" id="SPELLING_ERROR_4"&gt;view ports&lt;/span&gt; (I &lt;span class="blsp-spelling-corrected" id="SPELLING_ERROR_5"&gt;haven't&lt;/span&gt; tested an upper limit) and each view port is independently &lt;span class="blsp-spelling-corrected" id="SPELLING_ERROR_6"&gt;controlled&lt;/span&gt;, updated and rendered. They can share scene data or use entirely &lt;span class="blsp-spelling-corrected" id="SPELLING_ERROR_7"&gt;separate&lt;/span&gt; data.&lt;br /&gt;&lt;br /&gt;Uses for this within my plans for Decade are currently limited. It was implemented for my enjoyment rather than for a real need, however it should become useful for rear view when in a car, split screen multiple players etc..&lt;br /&gt;&lt;br /&gt;&lt;a href="http://2.bp.blogspot.com/_awzb2-vllx8/Rkrs35U6OjI/AAAAAAAAAHg/baQnQnaEFTg/s1600-h/multiple_viewports_4_16-05-07.JPG"&gt;&lt;img id="BLOGGER_PHOTO_ID_5065121175957027378" style="DISPLAY: block; MARGIN: 0px auto 10px; CURSOR: hand; TEXT-ALIGN: center" alt="" src="http://2.bp.blogspot.com/_awzb2-vllx8/Rkrs35U6OjI/AAAAAAAAAHg/baQnQnaEFTg/s400/multiple_viewports_4_16-05-07.JPG" border="0" /&gt;&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2766425237491213801-3415191714919052330?l=decadeengine.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://decadeengine.blogspot.com/feeds/3415191714919052330/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://decadeengine.blogspot.com/2007/05/multiple-view-ports.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2766425237491213801/posts/default/3415191714919052330'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2766425237491213801/posts/default/3415191714919052330'/><link rel='alternate' type='text/html' href='http://decadeengine.blogspot.com/2007/05/multiple-view-ports.html' title='Multiple View Ports'/><author><name>Ciarán McCormack</name><uri>http://www.blogger.com/profile/12300242420318331807</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://1.bp.blogspot.com/_awzb2-vllx8/Rkrs3pU6OiI/AAAAAAAAAHY/JL48pN3pmeA/s72-c/multiple_viewports_2_16-05-07.JPG' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2766425237491213801.post-3517266557005582436</id><published>2007-05-12T13:15:00.000+01:00</published><updated>2007-05-29T22:48:47.473+01:00</updated><title type='text'>The Sky's the Limit</title><content type='html'>Sky Boxes have been added to Decade, and as a friend has commented they give the scene atmosphere in more than 1 &lt;span class="blsp-spelling-corrected" id="SPELLING_ERROR_0"&gt;sense&lt;/span&gt;. The &lt;span class="blsp-spelling-corrected" id="SPELLING_ERROR_1"&gt;sky boxes&lt;/span&gt; used were taken from &lt;a href="http://www.hazelwhorley.com/textures.html"&gt;Hazel &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_2"&gt;Whorley&lt;/span&gt;&lt;/a&gt; who offers his creations free for use in non-commercial projects. They are some of the best free sky box textures I have ever seen.&lt;br /&gt;&lt;br /&gt;I will use sky boxes for a while with Decade however I want to soon implement sky domes. They have many advantages over &lt;span class="blsp-spelling-corrected" id="SPELLING_ERROR_3"&gt;sky boxes&lt;/span&gt;. Due to the cube nature of the sky box it is very difficult to animate the sky without the cube structure becoming obvious to the user. The dome removes this and will allow me to set the time of day and add procedural clouds.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href="http://3.bp.blogspot.com/_awzb2-vllx8/RkWyTAVnJ0I/AAAAAAAAAHQ/oOGDbxLKXQU/s1600-h/screen1_12-05-07.JPG"&gt;&lt;img id="BLOGGER_PHOTO_ID_5063649395625895746" style="DISPLAY: block; MARGIN: 0px auto 10px; CURSOR: hand; TEXT-ALIGN: center" alt="" src="http://3.bp.blogspot.com/_awzb2-vllx8/RkWyTAVnJ0I/AAAAAAAAAHQ/oOGDbxLKXQU/s400/screen1_12-05-07.JPG" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;a href="http://3.bp.blogspot.com/_awzb2-vllx8/RkWwTAVnJyI/AAAAAAAAAHA/31IoVI6zCiw/s1600-h/screen3_12-05-07.JPG"&gt;&lt;img id="BLOGGER_PHOTO_ID_5063647196602640162" style="DISPLAY: block; MARGIN: 0px auto 10px; CURSOR: hand; TEXT-ALIGN: center" alt="" src="http://3.bp.blogspot.com/_awzb2-vllx8/RkWwTAVnJyI/AAAAAAAAAHA/31IoVI6zCiw/s400/screen3_12-05-07.JPG" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;a href="http://4.bp.blogspot.com/_awzb2-vllx8/RkWwTQVnJzI/AAAAAAAAAHI/B8k8i5dxVeE/s1600-h/screen2_12-05-07.JPG"&gt;&lt;img id="BLOGGER_PHOTO_ID_5063647200897607474" style="DISPLAY: block; MARGIN: 0px auto 10px; CURSOR: hand; TEXT-ALIGN: center" alt="" src="http://4.bp.blogspot.com/_awzb2-vllx8/RkWwTQVnJzI/AAAAAAAAAHI/B8k8i5dxVeE/s400/screen2_12-05-07.JPG" border="0" /&gt;&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2766425237491213801-3517266557005582436?l=decadeengine.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://decadeengine.blogspot.com/feeds/3517266557005582436/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://decadeengine.blogspot.com/2007/05/skies-limit.html#comment-form' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2766425237491213801/posts/default/3517266557005582436'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2766425237491213801/posts/default/3517266557005582436'/><link rel='alternate' type='text/html' href='http://decadeengine.blogspot.com/2007/05/skies-limit.html' title='The Sky&apos;s the Limit'/><author><name>Ciarán McCormack</name><uri>http://www.blogger.com/profile/12300242420318331807</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://3.bp.blogspot.com/_awzb2-vllx8/RkWyTAVnJ0I/AAAAAAAAAHQ/oOGDbxLKXQU/s72-c/screen1_12-05-07.JPG' height='72' width='72'/><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2766425237491213801.post-5695500377667400714</id><published>2007-05-10T13:23:00.000+01:00</published><updated>2007-05-29T22:49:20.036+01:00</updated><title type='text'>Erosion Filters</title><content type='html'>Having put the issue raised in blog entry &lt;a href="http://decadeengine.blogspot.com/2007/04/if-man-owns-land-land-owns-him-ralph.html"&gt;If a man owns land, the land owns him&lt;/a&gt; on the to "Fix It Later" pile I continued development of Decade. All my documented issues are always on my mind as I research and develop, so yesterday while searching through random Terrain documents I found a &lt;a href="http://www.gamedev.net/reference/articles/article2164.asp"&gt;Box Filtering Height Maps for Smooth Rolling Hills&lt;/a&gt; tutorial and immediately thought it might be useful. Even though I am not always going to want to have rolling hills I thought that such a method might enable me store the terrain in its original 1 or 2 byte format instead of using 4 byte floats.&lt;br /&gt;&lt;br /&gt;&lt;div align="center"&gt;&lt;a href="http://3.bp.blogspot.com/_awzb2-vllx8/RkLyvwVnJtI/AAAAAAAAAGY/Ie2VwV04bnA/s1600-h/wireframe_original-10-05-07.JPG"&gt;&lt;img id="BLOGGER_PHOTO_ID_5062875833361180370" style="DISPLAY: block; MARGIN: 0px auto 10px; CURSOR: hand; TEXT-ALIGN: center" alt="" src="http://3.bp.blogspot.com/_awzb2-vllx8/RkLyvwVnJtI/AAAAAAAAAGY/Ie2VwV04bnA/s400/wireframe_original-10-05-07.JPG" border="0" /&gt;&lt;/a&gt; &lt;span style="font-size:78%;"&gt;Terrain with height values stored in 1 byte&lt;/span&gt;&lt;/div&gt;&lt;span style="font-size:78%;"&gt;&lt;/span&gt;&lt;div align="center"&gt;&lt;br /&gt;&lt;/div&gt;&lt;p align="center"&gt;&lt;a href="http://3.bp.blogspot.com/_awzb2-vllx8/RkLyvwVnJuI/AAAAAAAAAGg/jFxrVJGEd20/s1600-h/wireframe_floats-10-05-07.JPG"&gt;&lt;img id="BLOGGER_PHOTO_ID_5062875833361180386" style="DISPLAY: block; MARGIN: 0px auto 10px; CURSOR: hand; TEXT-ALIGN: center" alt="" src="http://3.bp.blogspot.com/_awzb2-vllx8/RkLyvwVnJuI/AAAAAAAAAGg/jFxrVJGEd20/s400/wireframe_floats-10-05-07.JPG" border="0" /&gt;&lt;/a&gt; &lt;span style="font-size:78%;"&gt;Terrain with height values stored in 4 bytes&lt;/span&gt;&lt;/p&gt;&lt;a href="http://4.bp.blogspot.com/_awzb2-vllx8/RkLywAVnJvI/AAAAAAAAAGo/OEsqd38iWno/s1600-h/wireframe_filtered1_1-10-05-07.JPG"&gt;&lt;img id="BLOGGER_PHOTO_ID_5062875837656147698" style="DISPLAY: block; MARGIN: 0px auto 10px; CURSOR: hand; TEXT-ALIGN: center" alt="" src="http://4.bp.blogspot.com/_awzb2-vllx8/RkLywAVnJvI/AAAAAAAAAGo/OEsqd38iWno/s400/wireframe_filtered1_1-10-05-07.JPG" border="0" /&gt; &lt;p align="center"&gt;&lt;/a&gt;&lt;/p&gt;&lt;span style="font-size:78%;"&gt;Terrain with height values stored in 1 byte and modified with Erosion Filter of Box Size 3 and 1 &lt;span class="blsp-spelling-corrected" id="SPELLING_ERROR_0"&gt;Iteration&lt;/span&gt;&lt;/span&gt; &lt;p align="left"&gt;As you can see, running the Erosion Filter on the terrain greatly improves the quality of the 1 byte &lt;span class="blsp-spelling-corrected" id="SPELLING_ERROR_1"&gt;height field&lt;/span&gt;. (When I say 1 byte height field I mean that the data in the .raw file was stored in bytes. The height field is still stored in 4 bytes (float) within Decade). There is a little loss of detail compared to the 4 byte terrain however depending on the game and environment this may be acceptable.&lt;/p&gt;&lt;a href="http://4.bp.blogspot.com/_awzb2-vllx8/RkLywAVnJwI/AAAAAAAAAGw/SJHibIQ5n0Q/s1600-h/wireframe_filtered5_5-10-05-07.JPG"&gt;&lt;img id="BLOGGER_PHOTO_ID_5062875837656147714" style="DISPLAY: block; MARGIN: 0px auto 10px; CURSOR: hand; TEXT-ALIGN: center" alt="" src="http://4.bp.blogspot.com/_awzb2-vllx8/RkLywAVnJwI/AAAAAAAAAGw/SJHibIQ5n0Q/s400/wireframe_filtered5_5-10-05-07.JPG" border="0" /&gt; &lt;p align="center"&gt;&lt;/a&gt;&lt;/p&gt;&lt;span style="font-size:78%;"&gt;Terrain with height values stored in 1 byte and modified with Erosion Filter of Box Size 11 and 5 &lt;span class="blsp-spelling-corrected" id="SPELLING_ERROR_2"&gt;Iteration&lt;/span&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;Care has to be taken when using the Erosion Filter. As you can see above running with too large a box size over many &lt;span class="blsp-spelling-corrected" id="SPELLING_ERROR_3"&gt;iterations&lt;/span&gt; starts to remove &lt;span class="blsp-spelling-corrected" id="SPELLING_ERROR_4"&gt;allot&lt;/span&gt; of the detail from the terrain resulting in a flowing rolling landscape. Again, this may be desirable in certain instances and not in others.&lt;br /&gt;&lt;br /&gt;What this has thought me is that there is no right answer to the question I am asking. It all depends on personal preference and the requirements of the game at that time. To &lt;span class="blsp-spelling-corrected" id="SPELLING_ERROR_5"&gt;accommodate&lt;/span&gt; this I am going to allow a broad range of options. My custom &lt;span class="blsp-spelling-corrected" id="SPELLING_ERROR_6"&gt;height map&lt;/span&gt; file will be modified to allow the user specify how the data is stored.&lt;br /&gt;&lt;br /&gt;Currently the simple file type is&lt;br /&gt;Width (2 Bytes)&lt;br /&gt;Length (2 Bytes)&lt;br /&gt;Data (Width * Length * 4 Bytes)&lt;br /&gt;&lt;br /&gt;so by adding in a type field the user can save and load as they desire&lt;br /&gt;&lt;br /&gt;Width (2 Bytes)&lt;br /&gt;Length ( 2 Bytes)&lt;br /&gt;Type (1 Byte)&lt;br /&gt;Data( Width * Length * Type Bytes)&lt;br /&gt;&lt;br /&gt;I hope that this,along with the box and any other &lt;span class="blsp-spelling-corrected" id="SPELLING_ERROR_7"&gt;Erosion&lt;/span&gt; Filters added later, will allow Decade deal with a large &lt;span class="blsp-spelling-corrected" id="SPELLING_ERROR_8"&gt;variety&lt;/span&gt; of requirements when rendering/storing its terrain.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2766425237491213801-5695500377667400714?l=decadeengine.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://decadeengine.blogspot.com/feeds/5695500377667400714/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://decadeengine.blogspot.com/2007/05/erosion-filters.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2766425237491213801/posts/default/5695500377667400714'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2766425237491213801/posts/default/5695500377667400714'/><link rel='alternate' type='text/html' href='http://decadeengine.blogspot.com/2007/05/erosion-filters.html' title='Erosion Filters'/><author><name>Ciarán McCormack</name><uri>http://www.blogger.com/profile/12300242420318331807</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://3.bp.blogspot.com/_awzb2-vllx8/RkLyvwVnJtI/AAAAAAAAAGY/Ie2VwV04bnA/s72-c/wireframe_original-10-05-07.JPG' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2766425237491213801.post-256290948172362814</id><published>2007-05-09T07:21:00.000+01:00</published><updated>2007-05-29T22:49:50.990+01:00</updated><title type='text'>A little forrest.</title><content type='html'>As I mentioned in a previous post, I really wanted to add trees and other vegetation to my terrain engine. I believed that this would greatly add to the atmosphere. My first desire was to create all these trees and plants procedurally. After searching online for a while I found a few good tutorials on how to achieve this but have decided to place that idea on hold for a while. &lt;span class="blsp-spelling-corrected" id="SPELLING_ERROR_0"&gt;Eventually&lt;/span&gt; I would love to do this. It would be great to have procedural plants on a procedural planet in a procedural solar system within a procedural universe. :)&lt;br /&gt;&lt;br /&gt;For now I have decided to use mesh's for the plants. Again, rather than waste my time trying to model them myself or look for &lt;span class="blsp-spelling-corrected" id="SPELLING_ERROR_1"&gt;appropriate&lt;/span&gt; free models online (any I found either looked wrong or were to complicated) I choose to purchase the tree packs from &lt;a href="http://www.loopix-project.com/"&gt;&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_2"&gt;Loopix&lt;/span&gt;&lt;/a&gt; These are decent quality, low poly trees which are ideal for my needs.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;&lt;a href="http://1.bp.blogspot.com/_awzb2-vllx8/RkGEwgVnJmI/AAAAAAAAAFg/hQEiYQatwPg/s1600-h/forrest_08-05-07.JPG"&gt;&lt;img id="BLOGGER_PHOTO_ID_5062473424990316130" style="DISPLAY: block; MARGIN: 0px auto 10px; CURSOR: hand; TEXT-ALIGN: center" alt="" src="http://1.bp.blogspot.com/_awzb2-vllx8/RkGEwgVnJmI/AAAAAAAAAFg/hQEiYQatwPg/s400/forrest_08-05-07.JPG" border="0" /&gt;&lt;/a&gt; &lt;/p&gt;&lt;p&gt;Currently a small selection of the available trees are just placed at random on the terrain. Already I think they add a whole new feeling to the demo.&lt;br /&gt;&lt;/p&gt;&lt;a href="http://2.bp.blogspot.com/_awzb2-vllx8/RkGEwwVnJnI/AAAAAAAAAFo/SaBq_yi92fo/s1600-h/forrest2_08-05-07.JPG"&gt;&lt;img id="BLOGGER_PHOTO_ID_5062473429285283442" style="DISPLAY: block; MARGIN: 0px auto 10px; CURSOR: hand; TEXT-ALIGN: center" alt="" src="http://2.bp.blogspot.com/_awzb2-vllx8/RkGEwwVnJnI/AAAAAAAAAFo/SaBq_yi92fo/s400/forrest2_08-05-07.JPG" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;a href="http://2.bp.blogspot.com/_awzb2-vllx8/RkGEwwVnJoI/AAAAAAAAAFw/INug0Pyyw5s/s1600-h/forrest3_08-05-07.JPG"&gt;&lt;img id="BLOGGER_PHOTO_ID_5062473429285283458" style="DISPLAY: block; MARGIN: 0px auto 10px; CURSOR: hand; TEXT-ALIGN: center" alt="" src="http://2.bp.blogspot.com/_awzb2-vllx8/RkGEwwVnJoI/AAAAAAAAAFw/INug0Pyyw5s/s400/forrest3_08-05-07.JPG" border="0" /&gt;&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2766425237491213801-256290948172362814?l=decadeengine.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://decadeengine.blogspot.com/feeds/256290948172362814/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://decadeengine.blogspot.com/2007/05/little-forrest.html#comment-form' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2766425237491213801/posts/default/256290948172362814'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2766425237491213801/posts/default/256290948172362814'/><link rel='alternate' type='text/html' href='http://decadeengine.blogspot.com/2007/05/little-forrest.html' title='A little forrest.'/><author><name>Ciarán McCormack</name><uri>http://www.blogger.com/profile/12300242420318331807</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://1.bp.blogspot.com/_awzb2-vllx8/RkGEwgVnJmI/AAAAAAAAAFg/hQEiYQatwPg/s72-c/forrest_08-05-07.JPG' height='72' width='72'/><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2766425237491213801.post-8737938308278571310</id><published>2007-05-04T19:20:00.000+01:00</published><updated>2007-05-29T22:50:12.736+01:00</updated><title type='text'>Procedural Texture Mapping</title><content type='html'>Decade can now generate its terrain textures procedurally. This is a big step as each terrain created automatically gets textured based on its unique attributes. Instead of just showing you a screenshot I will briefly explain how the textures are created.&lt;br /&gt;&lt;br /&gt;A set of base textures is gathered. These are plain textures of all the environments which will exist in the terrain. e.g. sand, grass, rock, mud, snow etc...&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href="http://3.bp.blogspot.com/_awzb2-vllx8/RjtP8gVnJiI/AAAAAAAAAFA/c1Q-spY3vdI/s1600-h/base_textures_04-05-07.JPG"&gt;&lt;img id="BLOGGER_PHOTO_ID_5060726507172210210" style="DISPLAY: block; MARGIN: 0px auto 10px; CURSOR: hand; TEXT-ALIGN: center" alt="" src="http://3.bp.blogspot.com/_awzb2-vllx8/RjtP8gVnJiI/AAAAAAAAAFA/c1Q-spY3vdI/s400/base_textures_04-05-07.JPG" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;Each of these environments is given&lt;br /&gt;&lt;ul&gt;&lt;li&gt;optimum height (The best height at which this environment exists)&lt;/li&gt;&lt;li&gt;min height (The minimum height at which this environment exists)&lt;/li&gt;&lt;li&gt;max height (The maximum height at which this environment exists)&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;&lt;a href="http://3.bp.blogspot.com/_awzb2-vllx8/RjtP8gVnJjI/AAAAAAAAAFI/_YFppdsBwj4/s1600-h/heightmap_04-05-07.JPG"&gt;&lt;img id="BLOGGER_PHOTO_ID_5060726507172210226" style="DISPLAY: block; MARGIN: 0px auto 10px; CURSOR: hand; TEXT-ALIGN: center" alt="" src="http://3.bp.blogspot.com/_awzb2-vllx8/RjtP8gVnJjI/AAAAAAAAAFI/_YFppdsBwj4/s400/heightmap_04-05-07.JPG" border="0" /&gt;&lt;/a&gt; &lt;/p&gt;&lt;p&gt;By cross referencing these values with the height map, the textures assigned to each terrain which exits at the given height are blended together with higher preference going to the more optimal terrain.&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;a href="http://4.bp.blogspot.com/_awzb2-vllx8/RjtP8wVnJkI/AAAAAAAAAFQ/Ip3kJFolUZQ/s1600-h/procedural_texture_04-05-07.JPG"&gt;&lt;img id="BLOGGER_PHOTO_ID_5060726511467177538" style="DISPLAY: block; MARGIN: 0px auto 10px; CURSOR: hand; TEXT-ALIGN: center" alt="" src="http://4.bp.blogspot.com/_awzb2-vllx8/RjtP8wVnJkI/AAAAAAAAAFQ/Ip3kJFolUZQ/s400/procedural_texture_04-05-07.JPG" border="0" /&gt;&lt;/a&gt;&lt;/p&gt;&lt;p&gt;The result is the above texture which is then applied to the terrain. For my first implementation of this algorithm I am happy with the results, however as always there are many &lt;span class="blsp-spelling-corrected" id="SPELLING_ERROR_0"&gt;improvements&lt;/span&gt; which need to be added.&lt;/p&gt;&lt;ul&gt;&lt;li&gt;Tiling textures instead of &lt;span class="blsp-spelling-corrected" id="SPELLING_ERROR_1"&gt;stretching&lt;/span&gt; them&lt;/li&gt;&lt;li&gt;Add support for applying the detail texture to the terrain texture at this stage to cards which do not support multi-&lt;span class="blsp-spelling-corrected" id="SPELLING_ERROR_2"&gt;texture&lt;/span&gt; can still have detail at no extra cost.&lt;/li&gt;&lt;li&gt;Some better logic for texture blending instead of just checking the height. The environment in a valley is different to that of a cliff face at the same height, or rocky outcrops on a snow covered mountain etc...&lt;/li&gt;&lt;li&gt;Add lighting so that features are enhanced. &lt;/li&gt;&lt;li&gt;Add vegetation to add more realism.&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;a href="http://1.bp.blogspot.com/_awzb2-vllx8/RjtP9AVnJlI/AAAAAAAAAFY/dqP21m7ao1Y/s1600-h/screenshot_04-05-07.JPG"&gt;&lt;img id="BLOGGER_PHOTO_ID_5060726515762144850" style="DISPLAY: block; MARGIN: 0px auto 10px; CURSOR: hand; TEXT-ALIGN: center" alt="" src="http://1.bp.blogspot.com/_awzb2-vllx8/RjtP9AVnJlI/AAAAAAAAAFY/dqP21m7ao1Y/s400/screenshot_04-05-07.JPG" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2766425237491213801-8737938308278571310?l=decadeengine.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://decadeengine.blogspot.com/feeds/8737938308278571310/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://decadeengine.blogspot.com/2007/05/procedural-texture-mapping.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2766425237491213801/posts/default/8737938308278571310'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2766425237491213801/posts/default/8737938308278571310'/><link rel='alternate' type='text/html' href='http://decadeengine.blogspot.com/2007/05/procedural-texture-mapping.html' title='Procedural Texture Mapping'/><author><name>Ciarán McCormack</name><uri>http://www.blogger.com/profile/12300242420318331807</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://3.bp.blogspot.com/_awzb2-vllx8/RjtP8gVnJiI/AAAAAAAAAFA/c1Q-spY3vdI/s72-c/base_textures_04-05-07.JPG' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2766425237491213801.post-352520551828167658</id><published>2007-04-30T23:05:00.000+01:00</published><updated>2007-05-29T22:50:44.886+01:00</updated><title type='text'>Bitter Sweet Success</title><content type='html'>Having quickly modified Decade, to store saved/generated terrains using floating point values rather than unsigned chars, I am happy and &lt;span class="blsp-spelling-corrected" id="SPELLING_ERROR_0"&gt;disappointed&lt;/span&gt; with the result.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://2.bp.blogspot.com/_awzb2-vllx8/RjZFvgVnJgI/AAAAAAAAAEw/8XmMTko4pMM/s1600-h/wireframe_30-04-07.JPG"&gt;&lt;img id="BLOGGER_PHOTO_ID_5059307913834079746" style="DISPLAY: block; MARGIN: 0px auto 10px; CURSOR: hand; TEXT-ALIGN: center" alt="" src="http://2.bp.blogspot.com/_awzb2-vllx8/RjZFvgVnJgI/AAAAAAAAAEw/8XmMTko4pMM/s400/wireframe_30-04-07.JPG" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;As you can see above the smoother gradient makes the terrain looks &lt;span class="blsp-spelling-corrected" id="SPELLING_ERROR_1"&gt;allot&lt;/span&gt; more natural. It has been commented that the &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_2"&gt;staired&lt;/span&gt; terrain looks cool, like &lt;span class="blsp-spelling-corrected" id="SPELLING_ERROR_3"&gt;contour&lt;/span&gt; farming, and &lt;span class="blsp-spelling-corrected" id="SPELLING_ERROR_4"&gt;perhaps&lt;/span&gt; it does in unique circumstances but it will not work for the terrain in general. Despite this success the loading/saving time and file size has been affected even more than predicted. Huge &lt;span class="blsp-spelling-corrected" id="SPELLING_ERROR_5"&gt;Height Map&lt;/span&gt; files and long loading times are not acceptable.&lt;br /&gt;&lt;br /&gt;&lt;p&gt;&lt;a href="http://3.bp.blogspot.com/_awzb2-vllx8/RjZFvwVnJhI/AAAAAAAAAE4/s_gwgM2RpRY/s1600-h/filled_30-04-07.JPG"&gt;&lt;img id="BLOGGER_PHOTO_ID_5059307918129047058" style="DISPLAY: block; MARGIN: 0px auto 10px; CURSOR: hand; TEXT-ALIGN: center" alt="" src="http://3.bp.blogspot.com/_awzb2-vllx8/RjZFvwVnJhI/AAAAAAAAAE4/s_gwgM2RpRY/s400/filled_30-04-07.JPG" border="0" /&gt;&lt;/a&gt;Some more research needs to be done for terrain storing and loading. Different &lt;span class="blsp-spelling-corrected" id="SPELLING_ERROR_6"&gt;possibilities&lt;/span&gt; which instantly come to mind which may or may not work are&lt;/p&gt;&lt;ul&gt;&lt;li&gt;Split the terrain over many files and load the segments coming into view on another thread&lt;/li&gt;&lt;li&gt;Store the terrain in the original .raw file and use some logic to smooth the &lt;span class="blsp-spelling-corrected" id="SPELLING_ERROR_7"&gt;vertices's&lt;/span&gt;&lt;/li&gt;&lt;/ul&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2766425237491213801-352520551828167658?l=decadeengine.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://decadeengine.blogspot.com/feeds/352520551828167658/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://decadeengine.blogspot.com/2007/04/bitter-sweet-success.html#comment-form' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2766425237491213801/posts/default/352520551828167658'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2766425237491213801/posts/default/352520551828167658'/><link rel='alternate' type='text/html' href='http://decadeengine.blogspot.com/2007/04/bitter-sweet-success.html' title='Bitter Sweet Success'/><author><name>Ciarán McCormack</name><uri>http://www.blogger.com/profile/12300242420318331807</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://2.bp.blogspot.com/_awzb2-vllx8/RjZFvgVnJgI/AAAAAAAAAEw/8XmMTko4pMM/s72-c/wireframe_30-04-07.JPG' height='72' width='72'/><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2766425237491213801.post-3703454690510727890</id><published>2007-04-30T19:54:00.000+01:00</published><updated>2007-05-29T22:51:45.032+01:00</updated><title type='text'>If a man owns land, the land owns him - Ralph Waldo Emerson</title><content type='html'>Just back from a weekend break in London so I did not program for the past few days. Coming home yesterday we were delayed in the train station for 7 hours so while sitting around I had plenty of time to think about what I wanted to achieve with the terrain segment of the Decade Engine. Here are some improvements. (I know I said in my last post that I was just going to add Vertex Arrays and &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_0"&gt;VBO's&lt;/span&gt; but after some consideration I believe that the following additions are also required.)&lt;br /&gt;&lt;br /&gt;1) Change from using a .raw file to using my own custom format. The .raw file used 1 byte for each value. This limits the range of values from 0 to 255 and only whole numbers are included. I &lt;span class="blsp-spelling-corrected" id="SPELLING_ERROR_1"&gt;didn'&lt;/span&gt;t notice any issue with this when I was rendering small terrains (up to 512x512) however now that much larger terrains are being rendered 8192x8192 (134,217,728 faces) a very undesirable stair case effect is &lt;span class="blsp-spelling-corrected" id="SPELLING_ERROR_2"&gt;emerging&lt;/span&gt;. Take a look at the attached screenshots. As the values of the terrain are rounded the terrain grows in increments making it look unnatural. I am going to create my own file format which will use floats instead of unsigned chars. This has the advantage of being correctly able represent the terrain however will result in a larger file size and a longer read/write time for the file. I believe the advantage greatly outweighs the problems.&lt;br /&gt;&lt;br /&gt;&lt;div align="center"&gt;&lt;a href="http://1.bp.blogspot.com/_awzb2-vllx8/RjWvTgVnJeI/AAAAAAAAAEg/tt3GRVnEvj4/s1600-h/step_terrain_1_30-04-07.JPG"&gt;&lt;img id="BLOGGER_PHOTO_ID_5059142506053576162" style="DISPLAY: block; MARGIN: 0px auto 10px; CURSOR: hand; TEXT-ALIGN: center" alt="" src="http://1.bp.blogspot.com/_awzb2-vllx8/RjWvTgVnJeI/AAAAAAAAAEg/tt3GRVnEvj4/s400/step_terrain_1_30-04-07.JPG" border="0" /&gt;&lt;/a&gt;&lt;span style="font-size:78%;"&gt; Stepped Terrain caused by .raw file data storage&lt;/span&gt;&lt;/div&gt;&lt;br /&gt;2) Now that larger terrains are being rendered some more intelligent culling of patches is required. Simply checking if each patch is visible to the camera (by checking collision with the viewing frustum) is not enough. The mentioned 8192x8192 terrain segment is made up of 232,324 patches. With the current implementation this results in 232,324 frustum checks per frame. By adding a simple node tree most of these checks can be bypassed.&lt;br /&gt;&lt;br /&gt;A &lt;a href="http://en.wikipedia.org/wiki/Tree_data_structure"&gt;node tree&lt;/a&gt; is a method of subdividing the mesh (terrain in this instance) into smaller sections. For instance, with the terrain I would divide it horizontally and vertically through the centre resulting in 4 segments, top right, top left, bottom right and bottom left. These segments would then be recursively divided until the required tree depth is reached. When doing frustum checks the terrain algorithm would first check collision with the node tree. If the Top Right Segment (or any other segment) was not visible by the frustum all of its children could immediately be ignored as not visible. If the Tree Node is visible by the frustum each of its children would be checked etc..etc... I expect that this will give a huge performance increase when used with large terrains for both &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_3"&gt;geomipmapped&lt;/span&gt; and brute force terrains.&lt;br /&gt;&lt;br /&gt;&lt;p align="center"&gt;&lt;a href="http://1.bp.blogspot.com/_awzb2-vllx8/RjWvTgVnJfI/AAAAAAAAAEo/WnN8fusnOzg/s1600-h/step_terrain_2_30-04-07.JPG"&gt;&lt;img id="BLOGGER_PHOTO_ID_5059142506053576178" style="DISPLAY: block; MARGIN: 0px auto 10px; CURSOR: hand; TEXT-ALIGN: center" alt="" src="http://1.bp.blogspot.com/_awzb2-vllx8/RjWvTgVnJfI/AAAAAAAAAEo/WnN8fusnOzg/s400/step_terrain_2_30-04-07.JPG" border="0" /&gt;&lt;/a&gt;&lt;span style="font-size:78%;"&gt;Stepped Terrain caused by .raw file data storage&lt;/span&gt;&lt;/p&gt;&lt;p&gt;3) Add support for Vertex Arrays and &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_4"&gt;VBO's&lt;/span&gt; in &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_5"&gt;geomipmapped&lt;/span&gt; terrains.&lt;br /&gt;&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2766425237491213801-3703454690510727890?l=decadeengine.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://decadeengine.blogspot.com/feeds/3703454690510727890/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://decadeengine.blogspot.com/2007/04/if-man-owns-land-land-owns-him-ralph.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2766425237491213801/posts/default/3703454690510727890'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2766425237491213801/posts/default/3703454690510727890'/><link rel='alternate' type='text/html' href='http://decadeengine.blogspot.com/2007/04/if-man-owns-land-land-owns-him-ralph.html' title='If a man owns land, the land owns him - Ralph Waldo Emerson'/><author><name>Ciarán McCormack</name><uri>http://www.blogger.com/profile/12300242420318331807</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://1.bp.blogspot.com/_awzb2-vllx8/RjWvTgVnJeI/AAAAAAAAAEg/tt3GRVnEvj4/s72-c/step_terrain_1_30-04-07.JPG' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2766425237491213801.post-340933713367869207</id><published>2007-04-27T08:22:00.000+01:00</published><updated>2007-05-29T22:52:14.475+01:00</updated><title type='text'>Patch Culling</title><content type='html'>&lt;div align="center"&gt;&lt;a href="http://3.bp.blogspot.com/_awzb2-vllx8/RjGzOAVnJbI/AAAAAAAAAEI/yAtZoUPhuqY/s1600-h/brute_force_27-04-07.JPG"&gt;&lt;img id="BLOGGER_PHOTO_ID_5058020909703964082" style="DISPLAY: block; MARGIN: 0px auto 10px; CURSOR: hand; TEXT-ALIGN: center" alt="" src="http://3.bp.blogspot.com/_awzb2-vllx8/RjGzOAVnJbI/AAAAAAAAAEI/yAtZoUPhuqY/s400/brute_force_27-04-07.JPG" border="0" /&gt;&lt;/a&gt;&lt;span style="font-size:78%;"&gt;Brute Force Terrain. 32258 Polygons Rendered&lt;/span&gt;&lt;/div&gt;&lt;br /&gt;As a further addition to the &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_0"&gt;Geomipmapped&lt;/span&gt; terrain I have added Patch Culling.&lt;br /&gt;&lt;br /&gt;In my original implementation of &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_1"&gt;Geomipmapping&lt;/span&gt; the distance from the camera to the terrain patch was calculated and from this the level of detail deciphered. If you remember your maths from school you will know that getting the distance between two points always returns a number which is greater than or equal to zero. Because of this no spatial relation between the objects is known so we still rendered patches which were out of view of the camera, &lt;span class="blsp-spelling-corrected" id="SPELLING_ERROR_2"&gt;although&lt;/span&gt; at its correct Level of Detail.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href="http://3.bp.blogspot.com/_awzb2-vllx8/RjGzOAVnJcI/AAAAAAAAAEQ/k3CoM1zjCPg/s1600-h/geo_no_culling_27-04-07.JPG"&gt;&lt;img id="BLOGGER_PHOTO_ID_5058020909703964098" style="DISPLAY: block; MARGIN: 0px auto 10px; CURSOR: hand; TEXT-ALIGN: center" alt="" src="http://3.bp.blogspot.com/_awzb2-vllx8/RjGzOAVnJcI/AAAAAAAAAEQ/k3CoM1zjCPg/s400/geo_no_culling_27-04-07.JPG" border="0" /&gt; &lt;p align="center"&gt;&lt;/a&gt;&lt;span style="font-size:78%;"&gt;&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_3"&gt;Geomipmapping&lt;/span&gt; with no Patch Culling. 5757 Polygons Rendered&lt;/span&gt;&lt;/p&gt;&lt;p&gt;With Patch Culling we simply check if the current patch is inside the &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_4"&gt;Fustrum&lt;/span&gt; of the Camera. A &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_5"&gt;fustrum&lt;/span&gt; is like a pyramid on its side, the pointy part at the lens of the camera extending out into the world. By doing some simple plane tests we can quickly and &lt;span class="blsp-spelling-corrected" id="SPELLING_ERROR_6"&gt;easily&lt;/span&gt; see if a point is inside this pyramid and therefore immediately ignore it if it is not. This does not only help us ignore faces to render, but we can also ignore patches to update so is useful for the &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_7"&gt;GPU&lt;/span&gt; and the CPU.&lt;/p&gt;&lt;p align="center"&gt;&lt;br /&gt;&lt;/p&gt;&lt;a href="http://3.bp.blogspot.com/_awzb2-vllx8/RjGzOAVnJdI/AAAAAAAAAEY/KkPsmEL1Q24/s1600-h/geo_culling_27-04-07.JPG"&gt;&lt;img id="BLOGGER_PHOTO_ID_5058020909703964114" style="DISPLAY: block; MARGIN: 0px auto 10px; CURSOR: hand; TEXT-ALIGN: center" alt="" src="http://3.bp.blogspot.com/_awzb2-vllx8/RjGzOAVnJdI/AAAAAAAAAEY/KkPsmEL1Q24/s400/geo_culling_27-04-07.JPG" border="0" /&gt; &lt;p align="center"&gt;&lt;/a&gt;&lt;span style="font-size:78%;"&gt;&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_8"&gt;Geomipmapping&lt;/span&gt; with Patch Culling. 2192 Polygons Rendered&lt;/span&gt;&lt;/p&gt;&lt;p align="left"&gt;The final addition to my &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_9"&gt;Geomipmapped&lt;/span&gt; Terrain (for now) is to add support for Vertex Arrays and &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_10"&gt;VBO's&lt;/span&gt;. I hope that this will increase the fps but it will also keep the render code &lt;span class="blsp-spelling-corrected" id="SPELLING_ERROR_11"&gt;separate&lt;/span&gt; from the terrain code therefore keep me on track for an engine which should be easier to update to &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_12"&gt;DX&lt;/span&gt;.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2766425237491213801-340933713367869207?l=decadeengine.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://decadeengine.blogspot.com/feeds/340933713367869207/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://decadeengine.blogspot.com/2007/04/patch-culling.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2766425237491213801/posts/default/340933713367869207'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2766425237491213801/posts/default/340933713367869207'/><link rel='alternate' type='text/html' href='http://decadeengine.blogspot.com/2007/04/patch-culling.html' title='Patch Culling'/><author><name>Ciarán McCormack</name><uri>http://www.blogger.com/profile/12300242420318331807</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://3.bp.blogspot.com/_awzb2-vllx8/RjGzOAVnJbI/AAAAAAAAAEI/yAtZoUPhuqY/s72-c/brute_force_27-04-07.JPG' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2766425237491213801.post-3154395954472938194</id><published>2007-04-24T08:04:00.000+01:00</published><updated>2007-05-29T22:52:44.827+01:00</updated><title type='text'>Geomipmapping</title><content type='html'>&lt;a href="http://en.wikipedia.org/wiki/Level_of_detail"&gt;&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_0"&gt;Geomipmapping&lt;/span&gt;&lt;/a&gt; my first implementation of a CLOD algorithm, is working in its most basic form. The images below show the different outputs from the algorithms. To render a segment of terrain which is 128x128 Brute Force renders 32510 faces while &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_1"&gt;Geomipmapping&lt;/span&gt; only has to render 1240 in this instance (this varies depending on camera position).&lt;br /&gt;&lt;br /&gt;&lt;div align="center"&gt;&lt;a href="http://2.bp.blogspot.com/_awzb2-vllx8/Ri3KYJfqHoI/AAAAAAAAAD4/i9evcB3mUG0/s1600-h/wireframe_24042007.JPG"&gt;&lt;img id="BLOGGER_PHOTO_ID_5056920472821309058" style="DISPLAY: block; MARGIN: 0px auto 10px; CURSOR: hand; TEXT-ALIGN: center" alt="" src="http://2.bp.blogspot.com/_awzb2-vllx8/Ri3KYJfqHoI/AAAAAAAAAD4/i9evcB3mUG0/s400/wireframe_24042007.JPG" border="0" /&gt;&lt;/a&gt; &lt;span style="font-size:78%;"&gt;Brute Force and &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_2"&gt;Geomipmapped&lt;/span&gt; Terrains Rendered in Wire Frame&lt;/span&gt;&lt;/div&gt;&lt;span style="font-size:78%;"&gt;&lt;/span&gt;&lt;div align="center"&gt;&lt;br /&gt;&lt;/div&gt;&lt;p align="center"&gt;&lt;a href="http://2.bp.blogspot.com/_awzb2-vllx8/Ri3KYJfqHpI/AAAAAAAAAEA/0vlFYeHd8Zc/s1600-h/textured_24042007.JPG"&gt;&lt;img id="BLOGGER_PHOTO_ID_5056920472821309074" style="DISPLAY: block; MARGIN: 0px auto 10px; CURSOR: hand; TEXT-ALIGN: center" alt="" src="http://2.bp.blogspot.com/_awzb2-vllx8/Ri3KYJfqHpI/AAAAAAAAAEA/0vlFYeHd8Zc/s400/textured_24042007.JPG" border="0" /&gt;&lt;/a&gt;&lt;span style="font-size:78%;"&gt; Brute Force and &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_3"&gt;Geomipmapped&lt;/span&gt; Terrains. (Very little visual difference)&lt;/span&gt;&lt;/p&gt;&lt;p&gt;Even at this stage I am happy with the frame rate increase. In the images shown you can see that &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_4"&gt;Geomipmapping&lt;/span&gt; achieves 72fps whereas Brute Force gets 67.7fps. This may not seem like much of an increase but please remember how the Brute Force &lt;span class="blsp-spelling-corrected" id="SPELLING_ERROR_5"&gt;vertices&lt;/span&gt; are stored and rendered. &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_6"&gt;VBO&lt;/span&gt; (Vertex Buffer Objects) are used therefore the &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_7"&gt;vertices&lt;/span&gt; are stored and rendered by the Graphics Card. My &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_8"&gt;Geomipmapping&lt;/span&gt; implementation currently renders all faces with individual software calls. If I do the same for Brute Force for the selected terrain its fps drops to about 54.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;By implementing Vertex Arrays or &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_9"&gt;VBO's&lt;/span&gt; for &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_10"&gt;Geomipmapping&lt;/span&gt;, which is also maintain my desire of keeping the algorithms and graphics &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_11"&gt;API&lt;/span&gt; calls &lt;span class="blsp-spelling-corrected" id="SPELLING_ERROR_12"&gt;separate&lt;/span&gt;, I expect to see a frame increase. Also by adding Frustum Culling on each of the terrain patches in the Geo terrain I can further reduce the number of &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_13"&gt;vertices&lt;/span&gt; to be rendered.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2766425237491213801-3154395954472938194?l=decadeengine.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://decadeengine.blogspot.com/feeds/3154395954472938194/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://decadeengine.blogspot.com/2007/04/geomipmapping.html#comment-form' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2766425237491213801/posts/default/3154395954472938194'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2766425237491213801/posts/default/3154395954472938194'/><link rel='alternate' type='text/html' href='http://decadeengine.blogspot.com/2007/04/geomipmapping.html' title='Geomipmapping'/><author><name>Ciarán McCormack</name><uri>http://www.blogger.com/profile/12300242420318331807</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://2.bp.blogspot.com/_awzb2-vllx8/Ri3KYJfqHoI/AAAAAAAAAD4/i9evcB3mUG0/s72-c/wireframe_24042007.JPG' height='72' width='72'/><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2766425237491213801.post-6134873992154774118</id><published>2007-04-22T15:02:00.000+01:00</published><updated>2007-05-29T22:52:58.103+01:00</updated><title type='text'>Memory feeds imagination - Amy Tan</title><content type='html'>Problems with Vertex and Index buffers are fixed. It took a long round-about way to get there. To isolate the issue I created a software renderer for the Vertex and Index Buffers. This involved parsing the vertex and index data during the render loop and using individual glTexCoord2f, glVertex3 etc... calls to render each face. This immediately showed that the vertex data was correct however the index data was only half populated.&lt;br /&gt;&lt;br /&gt;&lt;div align="center"&gt;&lt;a href="http://2.bp.blogspot.com/_awzb2-vllx8/Ritq_pfqHmI/AAAAAAAAADo/qf0NCjSAZeM/s1600-h/indexbuffer_problem1.JPG"&gt;&lt;img id="BLOGGER_PHOTO_ID_5056252648356453986" style="DISPLAY: block; MARGIN: 0px auto 10px; CURSOR: hand; TEXT-ALIGN: center" alt="" src="http://2.bp.blogspot.com/_awzb2-vllx8/Ritq_pfqHmI/AAAAAAAAADo/qf0NCjSAZeM/s400/indexbuffer_problem1.JPG" border="0" /&gt;&lt;/a&gt;&lt;span style="font-size:78%;"&gt; ASE Mesh incorrectly rendered with Index Buffers&lt;/span&gt;&lt;/div&gt;&lt;span style="font-size:78%;"&gt;&lt;/span&gt;&lt;div align="center"&gt;&lt;br /&gt;&lt;/div&gt;&lt;p align="center"&gt;&lt;a href="http://2.bp.blogspot.com/_awzb2-vllx8/Ritq_pfqHnI/AAAAAAAAADw/2uo_7suUqDw/s1600-h/indexbuffer_problem2.JPG"&gt;&lt;img id="BLOGGER_PHOTO_ID_5056252648356454002" style="DISPLAY: block; MARGIN: 0px auto 10px; CURSOR: hand; TEXT-ALIGN: center" alt="" src="http://2.bp.blogspot.com/_awzb2-vllx8/Ritq_pfqHnI/AAAAAAAAADw/2uo_7suUqDw/s400/indexbuffer_problem2.JPG" border="0" /&gt;&lt;/a&gt;&lt;span style="font-size:78%;"&gt; Terain Segment incorrectly rendered with Index Buffers&lt;/span&gt;&lt;/p&gt;&lt;span style="font-size:78%;"&gt;&lt;/span&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;e.g. In a terrain segment of of 8x8 there are 64 vertices, 128 faces and 384 indices. During the software rendering of the vertex and index buffers Decade engine crashed when the offset into the index buffer reached 147. It caused incorrect rendering or an Access violation because the value of the index buffer was 52685, but the vertex array has only 384 elements. Further investigation showed this to be an error with the memory copy functionality in the index buffer create function.&lt;br /&gt;&lt;br /&gt;Instead of&lt;br /&gt;memcpy( this-&gt;m_pusIndices, p_pusIndices, p_iNumberOfIndices );&lt;br /&gt;it should have been&lt;br /&gt;memcpy( this-&gt;m_&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_0"&gt;pusIndices&lt;/span&gt;, p_&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_1"&gt;pusIndices&lt;/span&gt;, p_&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_2"&gt;iNumberOfIndices&lt;/span&gt; * &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_3"&gt;sizeof&lt;/span&gt;(unsigned short) );&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Problem fixed.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2766425237491213801-6134873992154774118?l=decadeengine.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://decadeengine.blogspot.com/feeds/6134873992154774118/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://decadeengine.blogspot.com/2007/04/memory-feeds-imagination-amy-tan.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2766425237491213801/posts/default/6134873992154774118'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2766425237491213801/posts/default/6134873992154774118'/><link rel='alternate' type='text/html' href='http://decadeengine.blogspot.com/2007/04/memory-feeds-imagination-amy-tan.html' title='Memory feeds imagination - Amy Tan'/><author><name>Ciarán McCormack</name><uri>http://www.blogger.com/profile/12300242420318331807</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://2.bp.blogspot.com/_awzb2-vllx8/Ritq_pfqHmI/AAAAAAAAADo/qf0NCjSAZeM/s72-c/indexbuffer_problem1.JPG' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2766425237491213801.post-3701650675221360462</id><published>2007-04-17T17:50:00.000+01:00</published><updated>2007-05-29T22:53:21.471+01:00</updated><title type='text'>Fontastic</title><content type='html'>After some research and help from the good people at &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_0"&gt;GameDev&lt;/span&gt; I have found out there there is &lt;span class="blsp-spelling-corrected" id="SPELLING_ERROR_1"&gt;in fact&lt;/span&gt; no problem with the Vertex Arrays or &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_2"&gt;VBO's&lt;/span&gt;. The problem lies in the Font Object.&lt;br /&gt;&lt;br /&gt;A few days ago I wanted to show the Camera Position and Rotation so I quickly followed a Font Tutorial in order to display this info on screen. I &lt;span class="blsp-spelling-corrected" id="SPELLING_ERROR_3"&gt;didn't&lt;/span&gt; really pay attention to what I was doing as I planned on rewriting this anyway so I fell victim to Copy and Paste.&lt;br /&gt;&lt;br /&gt;Upon review I found that the font class used switches from 3D to 2D mode every time a string is rendered, so when I was rendering 6 lines of text this involved 6 Switches to 2D and 6 Switches back to 3D. When I changed this so that it switches to 2D, renders all text and then switches back to 3D I did find some &lt;span class="blsp-spelling-corrected" id="SPELLING_ERROR_4"&gt;improvements&lt;/span&gt;.&lt;br /&gt;&lt;br /&gt;Running on a lower end system&lt;br /&gt;&lt;br /&gt;Os : Windows &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_5"&gt;XP&lt;/span&gt; Pro SP 2&lt;br /&gt;CPU : Intel(R) Pentium 4 3.00GHz&lt;br /&gt;&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_6"&gt;GPU&lt;/span&gt; : Intel(R) 82915G/&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_7"&gt;GV&lt;/span&gt;/910&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_8"&gt;GL&lt;/span&gt; Express &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_9"&gt;Chipset&lt;/span&gt; Family (Driver Version 6.14.10.4410)&lt;br /&gt;Ram : 1GB&lt;br /&gt;&lt;br /&gt;I get the following results&lt;br /&gt;&lt;br /&gt;107fps when rendering in a nested Loop.&lt;br /&gt;128fps when rendering using Vertex Arrays.&lt;br /&gt;130fps when rendering using &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_10"&gt;VBO&lt;/span&gt;.&lt;br /&gt;&lt;br /&gt;I will now add in Index Buffers and see what results I get, as well as running on my home computer which has a good graphics card.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2766425237491213801-3701650675221360462?l=decadeengine.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://decadeengine.blogspot.com/feeds/3701650675221360462/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://decadeengine.blogspot.com/2007/04/fontastic.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2766425237491213801/posts/default/3701650675221360462'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2766425237491213801/posts/default/3701650675221360462'/><link rel='alternate' type='text/html' href='http://decadeengine.blogspot.com/2007/04/fontastic.html' title='Fontastic'/><author><name>Ciarán McCormack</name><uri>http://www.blogger.com/profile/12300242420318331807</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2766425237491213801.post-7298447481265531517</id><published>2007-04-16T08:05:00.000+01:00</published><updated>2007-05-29T22:53:45.529+01:00</updated><title type='text'>Vertex Buffer Objects and still no JOY</title><content type='html'>Yesterday I &lt;span class="blsp-spelling-corrected" id="SPELLING_ERROR_0"&gt;implemented&lt;/span&gt; Vertex Buffer Objects (&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_1"&gt;VBO's&lt;/span&gt;) into Decade Engine. Although I am still very happy with the code and the &lt;span class="blsp-spelling-corrected" id="SPELLING_ERROR_2"&gt;future&lt;/span&gt; portability to &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_3"&gt;DX&lt;/span&gt;, I am again &lt;span class="blsp-spelling-corrected" id="SPELLING_ERROR_4"&gt;disappointed&lt;/span&gt; with the performance results. There is limited increase in frame rate compared to software rendering and no increase compared to Vertex Arrays.&lt;br /&gt;&lt;br /&gt;For those interested in a more &lt;span class="blsp-spelling-corrected" id="SPELLING_ERROR_5"&gt;in depth&lt;/span&gt; description as well as any possible fixes, you can check out &lt;a href="http://www.gamedev.net/community/forums/topic.asp?topic_id=443916"&gt;here&lt;/a&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2766425237491213801-7298447481265531517?l=decadeengine.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://decadeengine.blogspot.com/feeds/7298447481265531517/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://decadeengine.blogspot.com/2007/04/vertex-buffer-objects-and-still-no-joy.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2766425237491213801/posts/default/7298447481265531517'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2766425237491213801/posts/default/7298447481265531517'/><link rel='alternate' type='text/html' href='http://decadeengine.blogspot.com/2007/04/vertex-buffer-objects-and-still-no-joy.html' title='Vertex Buffer Objects and still no JOY'/><author><name>Ciarán McCormack</name><uri>http://www.blogger.com/profile/12300242420318331807</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2766425237491213801.post-1099755089150140060</id><published>2007-04-14T10:40:00.000+01:00</published><updated>2007-05-29T22:54:13.181+01:00</updated><title type='text'>Vertex Arrays</title><content type='html'>Vertex and Index Arrays have been added to the Decade Engine. The Brute Force Terrain is now rendered using a Vertex Array as a Triangle Strip.&lt;br /&gt;&lt;br /&gt;Previously the Terrain was rendered in a nested loop, rendering X Triangle Strips, where X is the length of the terrain. Now when the terrain is created/loaded 1 Triangle Strip is created and loaded into a Vertex Array. At render time I simply ask &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_0"&gt;OpenGL&lt;/span&gt; to render this Vertex Array. Sample source for Vertex Arrays can be found at &lt;a href="http://www.morrowland.com/apron/tut_gl.php"&gt;here&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Sadly this did not give me the frame rate increase I was hoping for. I will have to investigate if there is a reason for this, and I will also implement &lt;a href="http://nehe.gamedev.net/data/lessons/lesson.asp?lesson=45"&gt;Vertex Buffer Objects&lt;/a&gt;. Despite the &lt;span class="blsp-spelling-corrected" id="SPELLING_ERROR_1"&gt;disappointing&lt;/span&gt; results the code is now &lt;span class="blsp-spelling-corrected" id="SPELLING_ERROR_2"&gt;allot&lt;/span&gt; more readable, &lt;span class="blsp-spelling-corrected" id="SPELLING_ERROR_3"&gt;allot&lt;/span&gt; more maintainable and the Terrain Object is &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_4"&gt;API&lt;/span&gt; independent. I will &lt;span class="blsp-spelling-corrected" id="SPELLING_ERROR_5"&gt;easily&lt;/span&gt; be able reuse the Object as-is when I code my &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_6"&gt;DirectX&lt;/span&gt; version of Decade. (if only things were ever that easy)&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href="http://3.bp.blogspot.com/_awzb2-vllx8/RiChlAEsNDI/AAAAAAAAADI/HlEDb3AYpvg/s1600-h/vertexarrays.JPG"&gt;&lt;img id="BLOGGER_PHOTO_ID_5053216438956602418" style="DISPLAY: block; MARGIN: 0px auto 10px; CURSOR: hand; TEXT-ALIGN: center" alt="" src="http://3.bp.blogspot.com/_awzb2-vllx8/RiChlAEsNDI/AAAAAAAAADI/HlEDb3AYpvg/s400/vertexarrays.JPG" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;Many areas of the engine are still in development&lt;/div&gt;&lt;ul&gt;&lt;li&gt;CLOD Terrain Renders&lt;/li&gt;&lt;li&gt;Terrain Texture Generation&lt;/li&gt;&lt;li&gt;Terrain Lighting&lt;/li&gt;&lt;li&gt;Applying Vertex and Index Buffers to Mesh Renders&lt;/li&gt;&lt;/ul&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2766425237491213801-1099755089150140060?l=decadeengine.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://decadeengine.blogspot.com/feeds/1099755089150140060/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://decadeengine.blogspot.com/2007/04/vertex-arrays.html#comment-form' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2766425237491213801/posts/default/1099755089150140060'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2766425237491213801/posts/default/1099755089150140060'/><link rel='alternate' type='text/html' href='http://decadeengine.blogspot.com/2007/04/vertex-arrays.html' title='Vertex Arrays'/><author><name>Ciarán McCormack</name><uri>http://www.blogger.com/profile/12300242420318331807</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://3.bp.blogspot.com/_awzb2-vllx8/RiChlAEsNDI/AAAAAAAAADI/HlEDb3AYpvg/s72-c/vertexarrays.JPG' height='72' width='72'/><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2766425237491213801.post-3956056840488094417</id><published>2007-04-10T20:32:00.000+01:00</published><updated>2007-05-29T22:54:28.168+01:00</updated><title type='text'>Terrain with Texture and Detail Map</title><content type='html'>The issue with the Terrain Texture has been fixed, or at least bypassed for now. I have stopped using &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_0"&gt;IPicture&lt;/span&gt; to load my textures and have written code to load the different file types. Currently &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_1"&gt;TGA&lt;/span&gt; and &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_2"&gt;BMP&lt;/span&gt; are supported. the &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_3"&gt;jpeg&lt;/span&gt; lib file causes errors as it was built in VS 2003 and I am using 2005. This can be reviewed later.&lt;br /&gt;&lt;br /&gt;As well as fixing the terrain &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_4"&gt;texturing&lt;/span&gt; I have added detail mapping. This uses multi &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_5"&gt;texturing&lt;/span&gt; to tile another "detail" texture over the terrain. I was quiet surprised to see what a huge difference such a simple technique could make to the realism of the terrain.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;div align="center"&gt;&lt;a href="http://3.bp.blogspot.com/_awzb2-vllx8/RhtnxQEsNBI/AAAAAAAAAC4/THJv_Iup7kE/s1600-h/terrainwithoutdetailmap.jpg"&gt;&lt;img id="BLOGGER_PHOTO_ID_5051745502852035602" style="DISPLAY: block; MARGIN: 0px auto 10px; CURSOR: hand; TEXT-ALIGN: center" alt="" src="http://3.bp.blogspot.com/_awzb2-vllx8/RhtnxQEsNBI/AAAAAAAAAC4/THJv_Iup7kE/s400/terrainwithoutdetailmap.jpg" border="0" /&gt;&lt;/a&gt; &lt;span style="font-size:78%;"&gt;Terrain without Detail Map&lt;/span&gt;&lt;/div&gt;&lt;div align="center"&gt;&lt;span style="font-size:78%;"&gt;&lt;/span&gt;&lt;/div&gt;&lt;div align="center"&gt;&lt;span style="font-size:78%;"&gt;&lt;/span&gt;&lt;/div&gt;&lt;div align="center"&gt;&lt;a href="http://4.bp.blogspot.com/_awzb2-vllx8/RhtnxgEsNCI/AAAAAAAAADA/E4tsFXvW3Co/s1600-h/terrainwithdetailmap.jpg"&gt;&lt;img id="BLOGGER_PHOTO_ID_5051745507147002914" style="DISPLAY: block; MARGIN: 0px auto 10px; CURSOR: hand; TEXT-ALIGN: center" alt="" src="http://4.bp.blogspot.com/_awzb2-vllx8/RhtnxgEsNCI/AAAAAAAAADA/E4tsFXvW3Co/s400/terrainwithdetailmap.jpg" border="0" /&gt;&lt;/a&gt;&lt;span style="font-size:78%;"&gt; Terrain with Detail Map&lt;/span&gt; &lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2766425237491213801-3956056840488094417?l=decadeengine.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://decadeengine.blogspot.com/feeds/3956056840488094417/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://decadeengine.blogspot.com/2007/04/issue-with-terrain-texture-has-been.html#comment-form' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2766425237491213801/posts/default/3956056840488094417'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2766425237491213801/posts/default/3956056840488094417'/><link rel='alternate' type='text/html' href='http://decadeengine.blogspot.com/2007/04/issue-with-terrain-texture-has-been.html' title='Terrain with Texture and Detail Map'/><author><name>Ciarán McCormack</name><uri>http://www.blogger.com/profile/12300242420318331807</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://3.bp.blogspot.com/_awzb2-vllx8/RhtnxQEsNBI/AAAAAAAAAC4/THJv_Iup7kE/s72-c/terrainwithoutdetailmap.jpg' height='72' width='72'/><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2766425237491213801.post-7927872913378075455</id><published>2007-04-07T23:37:00.000+01:00</published><updated>2007-05-29T22:54:46.702+01:00</updated><title type='text'>Terrain Engine</title><content type='html'>Development today focused on Terrain Rendering. Decade can now load a terrain from a .raw file and can also generate terrain using the Fault Formation and Mid Point Displacement Algorithms.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;div&gt;&lt;a href="http://4.bp.blogspot.com/_awzb2-vllx8/RhgdNv3DfSI/AAAAAAAAAB4/zG40rm5pV9Q/s1600-h/terrain01.JPG"&gt;&lt;img id="BLOGGER_PHOTO_ID_5050819104118897954" style="DISPLAY: block; MARGIN: 0px auto 10px; CURSOR: hand; TEXT-ALIGN: center" alt="" src="http://4.bp.blogspot.com/_awzb2-vllx8/RhgdNv3DfSI/AAAAAAAAAB4/zG40rm5pV9Q/s320/terrain01.JPG" border="0" /&gt;&lt;/a&gt; &lt;a href="http://4.bp.blogspot.com/_awzb2-vllx8/RhgdNv3DfTI/AAAAAAAAACA/MF8KpEARRxo/s1600-h/terrain02.JPG"&gt;&lt;img id="BLOGGER_PHOTO_ID_5050819104118897970" style="DISPLAY: block; MARGIN: 0px auto 10px; CURSOR: hand; TEXT-ALIGN: center" alt="" src="http://4.bp.blogspot.com/_awzb2-vllx8/RhgdNv3DfTI/AAAAAAAAACA/MF8KpEARRxo/s320/terrain02.JPG" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;a href="http://2.bp.blogspot.com/_awzb2-vllx8/RhgBrP3DfNI/AAAAAAAAABE/RfU18f7a5CE/s1600-h/terrain02.JPG"&gt;&lt;/a&gt;&lt;a href="http://4.bp.blogspot.com/_awzb2-vllx8/RhgBnv3DfMI/AAAAAAAAAA8/KdbIQDjKago/s1600-h/terrain01.JPG"&gt;&lt;/a&gt;Terrain is rendered using Brute Force. This means that all the the &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_0"&gt;vertices&lt;/span&gt; are rendered regardless of how far they are from the camera. On a small terrain like this that &lt;span class="blsp-spelling-corrected" id="SPELLING_ERROR_1"&gt;doesn't&lt;/span&gt; really matter however when the terrain grows larger it would slow then rendering to render all &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_2"&gt;vertices&lt;/span&gt; in this way. ROAM and CLOD will be added soon.&lt;br /&gt;&lt;br /&gt;&lt;div&gt;&lt;br /&gt;I also tried to add a texture to the terrain however there seems to be some problem. The texture is not complete even though the texture &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_3"&gt;vertices&lt;/span&gt; appear to be correct. I am using the &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_4"&gt;IPicture&lt;/span&gt; interface to load the textures so maybe there is a problem with this. &lt;span class="blsp-spelling-corrected" id="SPELLING_ERROR_5"&gt;Tomorrow&lt;/span&gt; I will try and manually load the textures and see if this fixes the problem.&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href="http://3.bp.blogspot.com/_awzb2-vllx8/RhgeFf3DfWI/AAAAAAAAACY/cEXRWbma_Aw/s1600-h/terrain03.JPG"&gt;&lt;img id="BLOGGER_PHOTO_ID_5050820061896605026" style="DISPLAY: block; MARGIN: 0px auto 10px; CURSOR: hand; TEXT-ALIGN: center" alt="" src="http://3.bp.blogspot.com/_awzb2-vllx8/RhgeFf3DfWI/AAAAAAAAACY/cEXRWbma_Aw/s320/terrain03.JPG" border="0" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2766425237491213801-7927872913378075455?l=decadeengine.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://decadeengine.blogspot.com/feeds/7927872913378075455/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://decadeengine.blogspot.com/2007/04/terrain-engine_07.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2766425237491213801/posts/default/7927872913378075455'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2766425237491213801/posts/default/7927872913378075455'/><link rel='alternate' type='text/html' href='http://decadeengine.blogspot.com/2007/04/terrain-engine_07.html' title='Terrain Engine'/><author><name>Ciarán McCormack</name><uri>http://www.blogger.com/profile/12300242420318331807</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://4.bp.blogspot.com/_awzb2-vllx8/RhgdNv3DfSI/AAAAAAAAAB4/zG40rm5pV9Q/s72-c/terrain01.JPG' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2766425237491213801.post-3304077409941744901</id><published>2007-04-05T20:19:00.000+01:00</published><updated>2007-05-29T22:54:59.839+01:00</updated><title type='text'>My First Entry</title><content type='html'>My very first blog and my very first entry. I never thought I would be a blogger. I find the whole idea strange and &lt;span class="blsp-spelling-corrected" id="SPELLING_ERROR_0"&gt;didn't&lt;/span&gt; think I would have anything worth the bother of blogging, however after being very impressed by a &lt;a href="http://dune-ii.blogspot.com/"&gt;development blog&lt;/a&gt; of a friend of mine I thought that a similar idea would be a good motivation and diary for my personal project.&lt;br /&gt;&lt;br /&gt;The Decade Engine is my new &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_1"&gt;OpenGL&lt;/span&gt; graphics engine with which I hope to create 3D games. It is so called because this year it has been 10 years since I first started programming, and with a personal project like this I &lt;span class="blsp-spelling-corrected" id="SPELLING_ERROR_2"&gt;wouldn't&lt;/span&gt; be surprised if it took 10 years to finish.&lt;br /&gt;&lt;br /&gt;I hope to use this blog to publish regular updated on the development and features of the engine and then details on the subsequent games made with Decade.&lt;br /&gt;&lt;br /&gt;&lt;em&gt;It starts. (Timon : The Lion King)&lt;/em&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2766425237491213801-3304077409941744901?l=decadeengine.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://decadeengine.blogspot.com/feeds/3304077409941744901/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://decadeengine.blogspot.com/2007/04/my-first-entry.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2766425237491213801/posts/default/3304077409941744901'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2766425237491213801/posts/default/3304077409941744901'/><link rel='alternate' type='text/html' href='http://decadeengine.blogspot.com/2007/04/my-first-entry.html' title='My First Entry'/><author><name>Ciarán McCormack</name><uri>http://www.blogger.com/profile/12300242420318331807</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2766425237491213801.post-1639263589825533607</id><published>2007-04-05T16:03:00.000+01:00</published><updated>2007-05-29T22:55:23.398+01:00</updated><title type='text'>First Images</title><content type='html'>&lt;div align="center"&gt;&lt;a href="http://1.bp.blogspot.com/_awzb2-vllx8/RhUQnv3DfII/AAAAAAAAAAc/PUbhlZ19S7c/s1600-h/one.JPG"&gt;&lt;img id="BLOGGER_PHOTO_ID_5049960832214203522" style="DISPLAY: block; MARGIN: 0px auto 10px; CURSOR: hand; TEXT-ALIGN: center" alt="" src="http://1.bp.blogspot.com/_awzb2-vllx8/RhUQnv3DfII/AAAAAAAAAAc/PUbhlZ19S7c/s320/one.JPG" border="0" /&gt;&lt;/a&gt;&lt;span style="font-size:78%;"&gt;ASE and 3&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_0"&gt;DS&lt;/span&gt; models with Alpha Blending and Bounding Spheres&lt;/span&gt; &lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href="http://1.bp.blogspot.com/_awzb2-vllx8/RhUQnv3DfJI/AAAAAAAAAAk/har6gpqJQeM/s1600-h/two.JPG"&gt;&lt;img id="BLOGGER_PHOTO_ID_5049960832214203538" style="DISPLAY: block; MARGIN: 0px auto 10px; CURSOR: hand; TEXT-ALIGN: center" alt="" src="http://1.bp.blogspot.com/_awzb2-vllx8/RhUQnv3DfJI/AAAAAAAAAAk/har6gpqJQeM/s320/two.JPG" border="0" /&gt; &lt;p align="center"&gt;&lt;/a&gt;&lt;span style="font-size:78%;"&gt;ASE and 3&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_1"&gt;DS&lt;/span&gt; models with Alpha Blending and Bounding &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_2"&gt;Rects&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-size:78%;"&gt;&lt;/span&gt;&lt;/p&gt;&lt;p align="left"&gt;Here are the first images from the Decade Engine. Nothing impressive to see as they are just tech demo's for my testing purposes. Current features of the engine are&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;div align="left"&gt;ASE Model Loading&lt;/div&gt;&lt;/li&gt;&lt;li&gt;&lt;div align="left"&gt;3&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_3"&gt;DS&lt;/span&gt; Model Loading (with animations)&lt;/div&gt;&lt;/li&gt;&lt;li&gt;&lt;div align="left"&gt;MD2 Model Loading (with animations)&lt;/div&gt;&lt;/li&gt;&lt;li&gt;&lt;div align="left"&gt;MD3 Model Loading (with animations)&lt;/div&gt;&lt;/li&gt;&lt;li&gt;&lt;div align="left"&gt;Camera with &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_4"&gt;Fustrum&lt;/span&gt; Culling&lt;/div&gt;&lt;/li&gt;&lt;li&gt;&lt;div align="left"&gt;Object &lt;span class="blsp-spelling-corrected" id="SPELLING_ERROR_5"&gt;Hierarchy&lt;/span&gt;&lt;/div&gt;&lt;/li&gt;&lt;li&gt;&lt;div align="left"&gt;Alpha Blending and Color Keying&lt;/div&gt;&lt;/li&gt;&lt;li&gt;&lt;div align="left"&gt;Bounding &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_6"&gt;Rect&lt;/span&gt; and Bounding Sphere&lt;/div&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p align="left"&gt;In &lt;span class="blsp-spelling-corrected" id="SPELLING_ERROR_7"&gt;progress&lt;/span&gt;&lt;/p&gt;&lt;ul&gt;&lt;li&gt;Terrain Rendering with Level of Details&lt;/li&gt;&lt;li&gt;Integration of the Open Dynamics Engine (&lt;a href="http://www.ode.org/"&gt;http://www.ode.org/&lt;/a&gt;)&lt;/li&gt;&lt;li&gt;&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_8"&gt;Scriptable&lt;/span&gt; Particle System&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2766425237491213801-1639263589825533607?l=decadeengine.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://decadeengine.blogspot.com/feeds/1639263589825533607/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://decadeengine.blogspot.com/2007/04/ase-and-3ds-models-with-alpha-blending.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2766425237491213801/posts/default/1639263589825533607'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2766425237491213801/posts/default/1639263589825533607'/><link rel='alternate' type='text/html' href='http://decadeengine.blogspot.com/2007/04/ase-and-3ds-models-with-alpha-blending.html' title='First Images'/><author><name>Ciarán McCormack</name><uri>http://www.blogger.com/profile/12300242420318331807</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://1.bp.blogspot.com/_awzb2-vllx8/RhUQnv3DfII/AAAAAAAAAAc/PUbhlZ19S7c/s72-c/one.JPG' height='72' width='72'/><thr:total>0</thr:total></entry></feed>
