<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
		<id>http://horde3d.org/wiki/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Wakko</id>
		<title>Horde3D Wiki - User contributions [en]</title>
		<link rel="self" type="application/atom+xml" href="http://horde3d.org/wiki/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Wakko"/>
		<link rel="alternate" type="text/html" href="http://horde3d.org/wiki/index.php?title=Special:Contributions/Wakko"/>
		<updated>2026-04-09T09:21:30Z</updated>
		<subtitle>User contributions</subtitle>
		<generator>MediaWiki 1.29.3</generator>

	<entry>
		<id>http://horde3d.org/wiki/index.php?title=Procedurally_generated_geometry_tutorial&amp;diff=689</id>
		<title>Procedurally generated geometry tutorial</title>
		<link rel="alternate" type="text/html" href="http://horde3d.org/wiki/index.php?title=Procedurally_generated_geometry_tutorial&amp;diff=689"/>
				<updated>2011-03-01T08:07:08Z</updated>
		
		<summary type="html">&lt;p&gt;Wakko: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;__NOTOC__ __NOEDITSECTION__{{ContentBlock|color=white|content={{!!}}&lt;br /&gt;
'''Work in progress   - Due to the current changes in the Horde API this tutorial will be delayed '''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
= Important notes=&lt;br /&gt;
* The code used here has been tested with Horde3D 1.0.0 beta2 and beta3 and will '''NOT''' work with the latest release (beta4)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=Overview=&lt;br /&gt;
==Basic approach==&lt;br /&gt;
To create and display a procedurally generated mesh that, instead of being loaded from a Horde3D Scene node and a geoemtry file(*.scene.xml, *.geo), will be created in-memory by some algorithm, you have to create a mesh first and then &amp;quot;fake&amp;quot; the .geo-file and the scene node itself and pass it to the engine.&lt;br /&gt;
&lt;br /&gt;
To do that you have to create your procedural geometry first. This is easy for simple shapes like single triangles, squares or triangle-strips, but will become way more difficult when we try to generate complex meshes, e.g. when we have a cloud of points in 3D space and have to describe which points make triangles, and which don't (calculating the triangle indices, texture coordinates and normals).&lt;br /&gt;
&lt;br /&gt;
When we have calculated the geometry itself we need to create a char-stream to make Horde believe the geometry has been read from a file and pass it to Horde as a geometry Resource.&lt;br /&gt;
The final step is to create a Horde3D Scene Node from our procedurally generated mesh and render it into our scene.&lt;br /&gt;
&lt;br /&gt;
=StreamGenerator=&lt;br /&gt;
&lt;br /&gt;
These classes are only for creating the character stream that will contain the geometry resource.&lt;br /&gt;
&lt;br /&gt;
{{CppSourceCode|&lt;br /&gt;
description= StreamGenerator.h| &lt;br /&gt;
code=&lt;br /&gt;
&amp;lt;source lang=&amp;quot;cpp&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
#pragma once&lt;br /&gt;
#include &amp;lt;sstream&amp;gt;&lt;br /&gt;
#include &amp;lt;string&amp;gt;&lt;br /&gt;
#include &amp;lt;iostream&amp;gt;&lt;br /&gt;
&lt;br /&gt;
class StreamGenerator &lt;br /&gt;
{&lt;br /&gt;
public:&lt;br /&gt;
	StreamGenerator();&lt;br /&gt;
	virtual ~StreamGenerator();&lt;br /&gt;
	virtual const char* getStream() = 0;&lt;br /&gt;
	virtual const int getStreamSize() = 0;&lt;br /&gt;
};&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{CppSourceCode|&lt;br /&gt;
description= StreamGenerator.cpp| &lt;br /&gt;
code=&lt;br /&gt;
&amp;lt;source lang=&amp;quot;cpp&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;quot;StreamGenerator.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
StreamGenerator::StreamGenerator() &lt;br /&gt;
{&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
StreamGenerator::~StreamGenerator()&lt;br /&gt;
{&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{CppSourceCode|&lt;br /&gt;
description= GeometryStreamGenerator.h| &lt;br /&gt;
code=&lt;br /&gt;
&amp;lt;source lang=&amp;quot;cpp&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
#pragma once&lt;br /&gt;
#include &amp;quot;StreamGenerator.h&amp;quot;&lt;br /&gt;
#include &amp;quot;CustomGeometry.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
class GeometryStreamGenerator : public StreamGenerator&lt;br /&gt;
{&lt;br /&gt;
private:&lt;br /&gt;
	std::stringstream* ss;&lt;br /&gt;
	void generate();&lt;br /&gt;
	int numVertices, numTriangleIndices;&lt;br /&gt;
	char* _stream;&lt;br /&gt;
	CustomGeometry* _geom;&lt;br /&gt;
&lt;br /&gt;
public:&lt;br /&gt;
	GeometryStreamGenerator(CustomGeometry* geom_);&lt;br /&gt;
	~GeometryStreamGenerator();&lt;br /&gt;
	const char* getStream();&lt;br /&gt;
	const std::stringstream* getStringStream() { return ss; };&lt;br /&gt;
	const int getStreamSize();&lt;br /&gt;
	const int getNumVertices();&lt;br /&gt;
	const int getNumTriangleIndices();&lt;br /&gt;
	void release();&lt;br /&gt;
};&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{CppSourceCode|&lt;br /&gt;
description= GeometryStreamGenerator.cpp| &lt;br /&gt;
code=&lt;br /&gt;
&amp;lt;source lang=&amp;quot;cpp&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;quot;GeometryStreamGenerator.h&amp;quot;&lt;br /&gt;
#include &amp;quot;time.h&amp;quot;&lt;br /&gt;
#include &amp;quot;utMath.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
GeometryStreamGenerator::GeometryStreamGenerator(CustomGeometry* geom_) : _geom(geom_)&lt;br /&gt;
{&lt;br /&gt;
	ss = new std::stringstream();&lt;br /&gt;
	generate();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
GeometryStreamGenerator::~GeometryStreamGenerator()&lt;br /&gt;
{&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void GeometryStreamGenerator::generate()&lt;br /&gt;
{&lt;br /&gt;
	numVertices = _geom-&amp;gt;getNumVertices();&lt;br /&gt;
	numTriangleIndices = _geom-&amp;gt;getNumTriangleIndices();&lt;br /&gt;
	const std::string _magicHeader = &amp;quot;H3DG&amp;quot;;&lt;br /&gt;
	const int _version = 5;&lt;br /&gt;
	const int _numJoints = 1;&lt;br /&gt;
	const float _identityMatrix[] = {	1.0f, 0.0f, 0.0f, 0.0f,  &lt;br /&gt;
						0.0f, 1.0f, 0.0f, 0.0f,  &lt;br /&gt;
						0.0f, 0.0f, 1.0f, 0.0f,  &lt;br /&gt;
						0.0f, 0.0f, 0.0f, 1.0f};&lt;br /&gt;
	const int _numVertexStreams = 3;&lt;br /&gt;
	const int _magicVertices = 0;&lt;br /&gt;
	const int _vertexStreamElementSize = 12;&lt;br /&gt;
	const float* _positions = _geom-&amp;gt;getPositions();&lt;br /&gt;
	const int _magicNormals = 1;&lt;br /&gt;
	const int _normalsStreamElementSize = 6;&lt;br /&gt;
	const float* _normals = _geom-&amp;gt;getNormals();&lt;br /&gt;
	const int _magicTextureCoords1 = 6;&lt;br /&gt;
	const int _texCoordStreamElementSize = 8;&lt;br /&gt;
	const float* _texCoords = _geom-&amp;gt;getTexCoords();&lt;br /&gt;
	const int* _triangleIndices = _geom-&amp;gt;getTriangleIndices();&lt;br /&gt;
	const int _numMorphTragets = 0;&lt;br /&gt;
	// header&lt;br /&gt;
	ss-&amp;gt;write(_magicHeader.c_str(), 4*sizeof(char));&lt;br /&gt;
	ss-&amp;gt;write((char*)&amp;amp;_version, sizeof(int));&lt;br /&gt;
	// joints (mandatory)&lt;br /&gt;
	ss-&amp;gt;write((char*)&amp;amp;_numJoints, sizeof(int));&lt;br /&gt;
	for (int i=0; i&amp;lt;16; ++i) {&lt;br /&gt;
		ss-&amp;gt;write((char*)&amp;amp;_identityMatrix[i], sizeof(float));&lt;br /&gt;
	}&lt;br /&gt;
	// vertices&lt;br /&gt;
	ss-&amp;gt;write((char*)&amp;amp;_numVertexStreams, sizeof(int));&lt;br /&gt;
	const int numVerts = _geom-&amp;gt;getNumVertices();&lt;br /&gt;
	ss-&amp;gt;write((char*)&amp;amp;numVerts, sizeof(int));&lt;br /&gt;
	ss-&amp;gt;write((char*)&amp;amp;_magicVertices, sizeof(int));&lt;br /&gt;
	ss-&amp;gt;write((char*)&amp;amp;_vertexStreamElementSize, sizeof(int));&lt;br /&gt;
	for (int i=0; i&amp;lt;_geom-&amp;gt;getNumVertices()*3; ++i) {&lt;br /&gt;
		ss-&amp;gt;write((char*)&amp;amp;_positions[i], sizeof(float));&lt;br /&gt;
	}&lt;br /&gt;
	// normals&lt;br /&gt;
	ss-&amp;gt;write((char*)&amp;amp;_magicNormals, sizeof(int));&lt;br /&gt;
	ss-&amp;gt;write((char*)&amp;amp;_normalsStreamElementSize, sizeof(int));&lt;br /&gt;
	for (int i=0; i&amp;lt;_geom-&amp;gt;getNumVertices()*3; ++i) {&lt;br /&gt;
		// do not forget to mutliply the value with 32767 and &lt;br /&gt;
		// then convert it to short before writing to the stream&lt;br /&gt;
		const short f = (short)(_normals[i]*32767);&lt;br /&gt;
		ss-&amp;gt;write((char*)&amp;amp;f, sizeof(short));&lt;br /&gt;
	}&lt;br /&gt;
	// texture coordinates&lt;br /&gt;
	ss-&amp;gt;write((char*)&amp;amp;_magicTextureCoords1, sizeof(int));&lt;br /&gt;
	ss-&amp;gt;write((char*)&amp;amp;_texCoordStreamElementSize, sizeof(int));&lt;br /&gt;
	for (int i=0; i&amp;lt;_geom-&amp;gt;getNumVertices()*2; ++i) {&lt;br /&gt;
		ss-&amp;gt;write((char*)&amp;amp;_texCoords[i], sizeof(float));&lt;br /&gt;
	}&lt;br /&gt;
	// triangle indices&lt;br /&gt;
	const int numTriangleIndices = _geom-&amp;gt;getNumTriangleIndices();&lt;br /&gt;
	ss-&amp;gt;write((char*)&amp;amp;numTriangleIndices, sizeof(int));&lt;br /&gt;
	for (int i=0; i&amp;lt;_geom-&amp;gt;getNumTriangleIndices(); ++i) {&lt;br /&gt;
		ss-&amp;gt;write((char*)&amp;amp;_triangleIndices[i], sizeof(int));&lt;br /&gt;
	}&lt;br /&gt;
	ss-&amp;gt;write((char*)&amp;amp;_numMorphTragets, sizeof(int));&lt;br /&gt;
	_stream = new char[ss-&amp;gt;tellp()];&lt;br /&gt;
	ss-&amp;gt;read(_stream, ss-&amp;gt;tellp());&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
const char* GeometryStreamGenerator::getStream()&lt;br /&gt;
{&lt;br /&gt;
	return _stream;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
const int GeometryStreamGenerator::getStreamSize() &lt;br /&gt;
{&lt;br /&gt;
	int t = (int)ss-&amp;gt;tellp();&lt;br /&gt;
	return t;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
const int GeometryStreamGenerator::getNumVertices()&lt;br /&gt;
{&lt;br /&gt;
	return numVertices;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
const int GeometryStreamGenerator::getNumTriangleIndices()&lt;br /&gt;
{&lt;br /&gt;
	return numTriangleIndices;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void GeometryStreamGenerator::release()&lt;br /&gt;
{&lt;br /&gt;
	ss-&amp;gt;flush();&lt;br /&gt;
	ss-&amp;gt;clear();&lt;br /&gt;
	delete ss;&lt;br /&gt;
	ss = 0;&lt;br /&gt;
	delete[] _stream;&lt;br /&gt;
	_stream = 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
=CustomGeometry base class=&lt;br /&gt;
&lt;br /&gt;
Base class for the custom geometry. This class currently contains lots of deprecated stuff, e.g. the update() function. This function was used to update an in-memory gemoetry resource in the &amp;quot;punk-rock&amp;quot;-way. Until Horde3D Beta3 the geometry resources were read-only, so directmanipulation of vertices was impossible. To modify the vertices I had to unload the geometry resource, re-create it with the new vertex-positions and load it into Horde again. '''This is not necessary any more because since Beta4 the geometry resources are not read-only anymore.'''&lt;br /&gt;
&lt;br /&gt;
All custom geometry classes should be derived from this class and implement the abstract functions as needed. (See the examples below)&lt;br /&gt;
&lt;br /&gt;
{{CppSourceCode|&lt;br /&gt;
description= CustomGeometry.h| &lt;br /&gt;
code=&lt;br /&gt;
&amp;lt;source lang=&amp;quot;cpp&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
#pragma once&lt;br /&gt;
/**&lt;br /&gt;
 * Abstract class for custom/dynamic geometry&lt;br /&gt;
 **/&lt;br /&gt;
#include &amp;quot;utMath.h&amp;quot;&lt;br /&gt;
#include &amp;quot;Horde3D.h&amp;quot;&lt;br /&gt;
#include &amp;lt;string&amp;gt;&lt;br /&gt;
&lt;br /&gt;
class CustomGeometry &lt;br /&gt;
{&lt;br /&gt;
protected:&lt;br /&gt;
	float _size;&lt;br /&gt;
	Vec3f _origin;&lt;br /&gt;
	int _numVertices;&lt;br /&gt;
	int _numTriangles;&lt;br /&gt;
	int _numTriangleIndices;&lt;br /&gt;
	float* _positions;&lt;br /&gt;
	float* _normals;&lt;br /&gt;
	float* _texCoords;&lt;br /&gt;
	int* _tIndices;&lt;br /&gt;
	std::string _name;&lt;br /&gt;
	NodeHandle _model;&lt;br /&gt;
	NodeHandle _parent;&lt;br /&gt;
	ResHandle _material;&lt;br /&gt;
	virtual void generatePositions() = 0;&lt;br /&gt;
	virtual void generateNormals() = 0;&lt;br /&gt;
	virtual void generateTexCoords() = 0;&lt;br /&gt;
	virtual void generateTriangleIndices() = 0;&lt;br /&gt;
&lt;br /&gt;
public:&lt;br /&gt;
	CustomGeometry();&lt;br /&gt;
	virtual void generate() = 0;&lt;br /&gt;
	const int getNumVertices() { return _numVertices; }&lt;br /&gt;
	const float* getPositions() { return _positions; }&lt;br /&gt;
	const float* getNormals() { return _normals; }&lt;br /&gt;
	const float* getTexCoords() { return _texCoords; }&lt;br /&gt;
	const int* getTriangleIndices() { return _tIndices; }&lt;br /&gt;
	const int getNumTriangles() { return _numTriangles; }&lt;br /&gt;
	const int getNumTriangleIndices() { return _numTriangleIndices; }&lt;br /&gt;
	void release();&lt;br /&gt;
	const Vec3f getInterpolatedNormal(Vec3f n1_, Vec3f n2_);&lt;br /&gt;
	// pass -1 as the parameter to leave the parent node unchanged&lt;br /&gt;
	void addCustomModelNode(NodeHandle parent_);&lt;br /&gt;
	bool removeCustomModelNode();&lt;br /&gt;
	void setMaterial(ResHandle material_) { _material = material_; }&lt;br /&gt;
	void setParent(NodeHandle parent_) { _parent = parent_; }&lt;br /&gt;
	NodeHandle getModel() { return _model; }&lt;br /&gt;
	ResHandle getMaterial() { return _material; }&lt;br /&gt;
	void update();&lt;br /&gt;
	Vec3f getOrigin() { return _origin; }&lt;br /&gt;
	void setOrigin(Vec3f origin_) { _origin = origin_; }&lt;br /&gt;
	const float getSize() { return _size; }&lt;br /&gt;
};&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{CppSourceCode|&lt;br /&gt;
description= CustomGeometry.cpp| &lt;br /&gt;
code=&lt;br /&gt;
&amp;lt;source lang=&amp;quot;cpp&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;quot;CustomGeometry.h&amp;quot;&lt;br /&gt;
#include &amp;lt;iostream&amp;gt;&lt;br /&gt;
#include &amp;lt;string&amp;gt;&lt;br /&gt;
#include &amp;lt;sstream&amp;gt;&lt;br /&gt;
#include &amp;lt;fstream&amp;gt;&lt;br /&gt;
#include &amp;quot;GeometryStreamGenerator.h&amp;quot;&lt;br /&gt;
#include &amp;quot;Horde3DUtils.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
CustomGeometry::CustomGeometry() : _name(&amp;quot;default&amp;quot;), _size(1)&lt;br /&gt;
{&lt;br /&gt;
	_origin = Vec3f(0, 0, 0);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void CustomGeometry::release()&lt;br /&gt;
{&lt;br /&gt;
	delete[] _positions;&lt;br /&gt;
	_positions = 0;&lt;br /&gt;
	delete[] _normals;&lt;br /&gt;
	_normals = 0;&lt;br /&gt;
	delete[] _texCoords;&lt;br /&gt;
	_texCoords = 0;&lt;br /&gt;
	delete[] _tIndices;&lt;br /&gt;
	_tIndices = 0;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
const Vec3f CustomGeometry::getInterpolatedNormal(Vec3f n1_, Vec3f n2_) &lt;br /&gt;
{&lt;br /&gt;
	Vec3f newNormal = n1_ + n2_;&lt;br /&gt;
	float length = newNormal.length();&lt;br /&gt;
	return newNormal/length;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void CustomGeometry::addCustomModelNode(NodeHandle parent_)&lt;br /&gt;
{&lt;br /&gt;
	//std::stringstream* sa = new std::stringstream();&lt;br /&gt;
	std::stringstream ss;&lt;br /&gt;
	if (parent_ != -1) &lt;br /&gt;
		_parent = parent_;&lt;br /&gt;
	ss&amp;lt;&amp;lt; &amp;quot;customGeometry-&amp;quot;;&lt;br /&gt;
	ss&amp;lt;&amp;lt;_name;&lt;br /&gt;
	GeometryStreamGenerator* gsg = new GeometryStreamGenerator(this);&lt;br /&gt;
	ResHandle customGeoRes = Horde3D::addResource(ResourceTypes::Geometry, ss.str().c_str(), 0);&lt;br /&gt;
	Horde3D::loadResource(customGeoRes, gsg-&amp;gt;getStream(), gsg-&amp;gt;getStreamSize());&lt;br /&gt;
	// model_node_name&lt;br /&gt;
	ss&amp;lt;&amp;lt;&amp;quot;-Node&amp;quot;;&lt;br /&gt;
	_model = Horde3D::addModelNode(_parent, ss.str().c_str(), customGeoRes);&lt;br /&gt;
	// mesh_name&lt;br /&gt;
	ss&amp;lt;&amp;lt;&amp;quot;-Mesh&amp;quot;;&lt;br /&gt;
	Horde3D::addMeshNode(_model, ss.str().c_str(), _material, 0, gsg-&amp;gt;getNumTriangleIndices(), 0, gsg-&amp;gt;getNumVertices()-1);&lt;br /&gt;
	Horde3DUtils::dumpMessages();&lt;br /&gt;
	ss.str(&amp;quot;&amp;quot;);&lt;br /&gt;
	ss.clear();&lt;br /&gt;
	ss.flush();&lt;br /&gt;
	gsg-&amp;gt;release();&lt;br /&gt;
	delete gsg;&lt;br /&gt;
	gsg = 0;&lt;br /&gt;
	//Horde3D::setNodeTransform(_model, _origin.x, _origin.y, _origin.z, 0, 0, 0, 1, 1, 1);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
bool CustomGeometry::removeCustomModelNode()&lt;br /&gt;
{&lt;br /&gt;
	std::stringstream* ss = new std::stringstream();&lt;br /&gt;
	*ss&amp;lt;&amp;lt; &amp;quot;customGeometry-&amp;quot;;&lt;br /&gt;
	*ss&amp;lt;&amp;lt;_name;&lt;br /&gt;
	ResHandle rh = Horde3D::findResource(ResourceTypes::Geometry, ss-&amp;gt;str().c_str());&lt;br /&gt;
	if (Horde3D::isResourceLoaded(rh)) {&lt;br /&gt;
		Horde3D::removeResource(rh);&lt;br /&gt;
		Horde3D::unloadResource(rh);&lt;br /&gt;
		Horde3D::removeNode(_model);&lt;br /&gt;
		Horde3D::releaseUnusedResources();&lt;br /&gt;
		Horde3DUtils::dumpMessages();&lt;br /&gt;
		delete ss;&lt;br /&gt;
		return true;&lt;br /&gt;
	}&lt;br /&gt;
	else &lt;br /&gt;
		return false;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void CustomGeometry::update()&lt;br /&gt;
{&lt;br /&gt;
	removeCustomModelNode();&lt;br /&gt;
	addCustomModelNode(-1);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
=Simple Square=&lt;br /&gt;
&lt;br /&gt;
A simple hard-coded square. This is pretty straight forward and demonstrates how to derive from the CustomGeometry class and how the triangle indices work.&lt;br /&gt;
&lt;br /&gt;
{{CppSourceCode|&lt;br /&gt;
description= DynamicSquare.h| &lt;br /&gt;
code=&lt;br /&gt;
&amp;lt;source lang=&amp;quot;cpp&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
/**&lt;br /&gt;
 * Class representing a square &lt;br /&gt;
 **/&lt;br /&gt;
#pragma once&lt;br /&gt;
#include &amp;quot;CustomGeometry.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
class DynamicSquare : public CustomGeometry&lt;br /&gt;
{&lt;br /&gt;
protected:&lt;br /&gt;
	virtual void generatePositions();&lt;br /&gt;
	virtual void generateNormals();&lt;br /&gt;
	virtual void generateTexCoords();&lt;br /&gt;
	virtual void generateTriangleIndices();&lt;br /&gt;
&lt;br /&gt;
public:&lt;br /&gt;
	DynamicSquare();&lt;br /&gt;
	virtual void generate();&lt;br /&gt;
	DynamicSquare(const float size_, const std::string name_);&lt;br /&gt;
};&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{CppSourceCode|&lt;br /&gt;
description= DynamicSquare.cpp| &lt;br /&gt;
code=&lt;br /&gt;
&amp;lt;source lang=&amp;quot;cpp&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;quot;DynamicSquare.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
DynamicSquare::DynamicSquare() : CustomGeometry()&lt;br /&gt;
{&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
DynamicSquare::DynamicSquare(const float size_, const std::string name_) &lt;br /&gt;
{&lt;br /&gt;
	_size = size_;&lt;br /&gt;
	_name = name_;&lt;br /&gt;
	_numVertices = 4;&lt;br /&gt;
	_numTriangles = 2;&lt;br /&gt;
	_numTriangleIndices = _numTriangles * 3;&lt;br /&gt;
	//generate();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void DynamicSquare::generate() &lt;br /&gt;
{&lt;br /&gt;
	generatePositions();&lt;br /&gt;
	generateNormals();&lt;br /&gt;
	generateTexCoords();&lt;br /&gt;
	generateTriangleIndices();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void DynamicSquare::generatePositions() &lt;br /&gt;
{&lt;br /&gt;
	_positions = new float[_numVertices * 3 * 2];&lt;br /&gt;
	// front left point (x/y/z)&lt;br /&gt;
	_positions[0] = _origin.x * _size - _size/2;&lt;br /&gt;
	_positions[1] = _origin.y;&lt;br /&gt;
	_positions[2] = _origin.z * _size -_size/2;&lt;br /&gt;
	// front right point (x/y/z)&lt;br /&gt;
	_positions[3] = _origin.x * _size + _size/2;&lt;br /&gt;
	_positions[4] = _origin.y;&lt;br /&gt;
	_positions[5] = _origin.z * _size - _size/2;&lt;br /&gt;
	// back left point (x/y/z)&lt;br /&gt;
	_positions[6] = _origin.x * _size - _size/2;&lt;br /&gt;
	_positions[7] = _origin.y;&lt;br /&gt;
	_positions[8] = _origin.z * _size + _size/2;&lt;br /&gt;
	// back right point (x/y/z)&lt;br /&gt;
	_positions[9] = _origin.x * _size + _size/2;&lt;br /&gt;
	_positions[10] = _origin.y;&lt;br /&gt;
	_positions[11] = _origin.z * _size + _size/2;&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void DynamicSquare::generateNormals() &lt;br /&gt;
{&lt;br /&gt;
	_normals = new float[_numVertices * 3];&lt;br /&gt;
	for (int i=0; i&amp;lt; 12; i+=3) {&lt;br /&gt;
		_normals[i] = 0;&lt;br /&gt;
		_normals[i+1] = 1;&lt;br /&gt;
		_normals[i+2] = 0;&lt;br /&gt;
	}&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void DynamicSquare::generateTexCoords()&lt;br /&gt;
{&lt;br /&gt;
	_texCoords = new float[_numVertices * 2];&lt;br /&gt;
	_texCoords[0] = 0.0f; &lt;br /&gt;
	_texCoords[1] = 0.0f;&lt;br /&gt;
	_texCoords[2] = 1.0f; &lt;br /&gt;
	_texCoords[3] = 0.0f;&lt;br /&gt;
	_texCoords[4] = 0.0f; &lt;br /&gt;
	_texCoords[5] = 1.0f;&lt;br /&gt;
	_texCoords[6] = 1.0f; &lt;br /&gt;
	_texCoords[7] = 1.0f;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void DynamicSquare::generateTriangleIndices() &lt;br /&gt;
{&lt;br /&gt;
	_tIndices = new int[_numTriangleIndices ];&lt;br /&gt;
	_tIndices[0] = 0;&lt;br /&gt;
	_tIndices[1] = 2;&lt;br /&gt;
	_tIndices[2] = 1;&lt;br /&gt;
	_tIndices[3] = 1;&lt;br /&gt;
	_tIndices[4] = 2;&lt;br /&gt;
	_tIndices[5] = 3;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
=Simple Grid=&lt;br /&gt;
&lt;br /&gt;
All the work above was made to create my own interactive terrain generator(screenshot on top of this page) for a A* pathfinding demonstrator. The Grid-class actually generates a 2-dimensional array of Vec3f(s) and allows to extrude each point and re-generate the mesh in realtime. The internal representation is writeable and in case of a change of any point the overridden update() function will be called to update the Horde3D geometry resource.&lt;br /&gt;
&lt;br /&gt;
{{CppSourceCode|&lt;br /&gt;
description= DynamicGrid.h| &lt;br /&gt;
code=&lt;br /&gt;
&amp;lt;source lang=&amp;quot;cpp&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
/**&lt;br /&gt;
 * Class representing a grid&lt;br /&gt;
 **/&lt;br /&gt;
#pragma once&lt;br /&gt;
#include &amp;quot;CustomGeometry.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
class DynamicGrid : public CustomGeometry&lt;br /&gt;
{&lt;br /&gt;
protected:&lt;br /&gt;
	virtual void generatePositions();&lt;br /&gt;
	virtual void generateNormals();&lt;br /&gt;
	virtual void generateTexCoords();&lt;br /&gt;
	virtual void generateTriangleIndices();&lt;br /&gt;
       // generate the internal representation of the grid (writeable to allow updates of single points!)&lt;br /&gt;
	void generateGrid();&lt;br /&gt;
	int _gridSize;&lt;br /&gt;
	Vec3f** _grid;&lt;br /&gt;
	std::string _fileName;&lt;br /&gt;
&lt;br /&gt;
public:&lt;br /&gt;
	DynamicGrid();&lt;br /&gt;
	virtual void generate();&lt;br /&gt;
	DynamicGrid(const float size_, const std::string name_, std::string fileName_);&lt;br /&gt;
	Vec3f getPointAt(int x_, int y_) { return _grid[y_][x_]; }&lt;br /&gt;
	// update a point of our grid (args: index x, index y, new position)&lt;br /&gt;
	void setPointAt(int x_, int y_, Vec3f newPos_) { _grid[y_][x_] = newPos_; }&lt;br /&gt;
	int getGridSize() { return _gridSize; }&lt;br /&gt;
	// overwrite update() from parent class&lt;br /&gt;
	void update();&lt;br /&gt;
	// read and write grids from/to files&lt;br /&gt;
	void saveGridToFile(std::string fileName_);&lt;br /&gt;
	bool readGridFromFile(std::string fileName_);&lt;br /&gt;
&lt;br /&gt;
};&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{CppSourceCode|&lt;br /&gt;
description= DynamicGrid.cpp| &lt;br /&gt;
code=&lt;br /&gt;
&amp;lt;source lang=&amp;quot;cpp&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;quot;DynamicGrid.h&amp;quot;&lt;br /&gt;
#include &amp;quot;rng.h&amp;quot;&lt;br /&gt;
#include &amp;lt;iostream&amp;gt;&lt;br /&gt;
#include &amp;lt;string&amp;gt;&lt;br /&gt;
#include &amp;lt;sstream&amp;gt;&lt;br /&gt;
#include &amp;lt;fstream&amp;gt;&lt;br /&gt;
#include &amp;quot;util.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
#define GRIDSIZE 50&lt;br /&gt;
&lt;br /&gt;
DynamicGrid::DynamicGrid() : CustomGeometry()&lt;br /&gt;
{&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
DynamicGrid::DynamicGrid(const float size_, const std::string name_, std::string fileName_) : _fileName(fileName_) &lt;br /&gt;
{&lt;br /&gt;
	_name = name_;&lt;br /&gt;
	_positions = 0;&lt;br /&gt;
	_normals = 0;&lt;br /&gt;
	_texCoords = 0;&lt;br /&gt;
	_tIndices = 0;&lt;br /&gt;
	readGridFromFile(_fileName);&lt;br /&gt;
	_numVertices = (_gridSize*_gridSize);&lt;br /&gt;
	_numTriangles = ((_gridSize - 1) * (_gridSize - 1)) * 2;&lt;br /&gt;
	_numTriangleIndices = _numTriangles * 3;&lt;br /&gt;
	_origin = Vec3f(-_size/2*_gridSize, 0, _size/2*_gridSize);&lt;br /&gt;
	/*&lt;br /&gt;
	std::cout&amp;lt;&amp;lt;&amp;quot;numVerts: &amp;quot;&amp;lt;&amp;lt;_numVertices&amp;lt;&amp;lt;std::endl;&lt;br /&gt;
	std::cout&amp;lt;&amp;lt;&amp;quot;numTris: &amp;quot;&amp;lt;&amp;lt;_numTriangles&amp;lt;&amp;lt;std::endl;&lt;br /&gt;
	std::cout&amp;lt;&amp;lt;&amp;quot;numTInds: &amp;quot;&amp;lt;&amp;lt;_numTriangleIndices&amp;lt;&amp;lt;std::endl;&lt;br /&gt;
	std::cout&amp;lt;&amp;lt;&amp;quot;size: &amp;quot;&amp;lt;&amp;lt;_size&amp;lt;&amp;lt;std::endl;&lt;br /&gt;
	*/&lt;br /&gt;
	//std::cout&amp;lt;&amp;lt;_origin.x&amp;lt;&amp;lt;&amp;quot;/&amp;quot;&amp;lt;&amp;lt;_origin.y&amp;lt;&amp;lt;&amp;quot;/&amp;quot;&amp;lt;&amp;lt;_origin.z&amp;lt;&amp;lt;std::endl;&lt;br /&gt;
	//generate();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void DynamicGrid::generate() &lt;br /&gt;
{&lt;br /&gt;
	if (!_grid)&lt;br /&gt;
		generateGrid();&lt;br /&gt;
	generatePositions();&lt;br /&gt;
	generateNormals();&lt;br /&gt;
	generateTexCoords();&lt;br /&gt;
	generateTriangleIndices();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// the following two functions could be combined into one single loop, but I left it this way for clarity...&lt;br /&gt;
/**&lt;br /&gt;
 * This function simply generates a 2-dimensional array of Vec3f(s) with slightly random height values&lt;br /&gt;
 **/&lt;br /&gt;
void DynamicGrid::generateGrid()&lt;br /&gt;
{&lt;br /&gt;
	RNG rng;&lt;br /&gt;
	_grid = new Vec3f*[_gridSize];&lt;br /&gt;
	for (int y=0; y&amp;lt;_gridSize; ++y) {&lt;br /&gt;
		_grid[y] = new Vec3f[_gridSize];&lt;br /&gt;
		for (int x=0; x&amp;lt;_gridSize; ++x) {&lt;br /&gt;
			long rand = (abs((int)rng.rand_int31()) %3);&lt;br /&gt;
			_grid[y][x] = Vec3f(_origin.x/2+_size/2*x, rand, _origin.z/2-_size/2*y);&lt;br /&gt;
			//std::cout&amp;lt;&amp;lt;_grid[y][x].x&amp;lt;&amp;lt;&amp;quot;/&amp;quot;&amp;lt;&amp;lt;_grid[y][x].y&amp;lt;&amp;lt;&amp;quot;/&amp;quot;&amp;lt;&amp;lt;_grid[y][x].z&amp;lt;&amp;lt;std::endl;&lt;br /&gt;
		}&lt;br /&gt;
	}&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/**&lt;br /&gt;
 * Convert the grid's positions into a Horde3D vertex array.&lt;br /&gt;
 **/&lt;br /&gt;
void DynamicGrid::generatePositions() &lt;br /&gt;
{&lt;br /&gt;
	_positions = new float[_numVertices*3];&lt;br /&gt;
	int counter = 0;&lt;br /&gt;
	for (int i=0; i&amp;lt;_numVertices*3; i+=3) {&lt;br /&gt;
		int y = counter / _gridSize;&lt;br /&gt;
		int x = counter % _gridSize;&lt;br /&gt;
		_positions[i] = _grid[y][x].x;&lt;br /&gt;
		_positions[i+1] = _grid[y][x].y;&lt;br /&gt;
		_positions[i+2] = _grid[y][x].z;&lt;br /&gt;
		++counter;&lt;br /&gt;
	}&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void DynamicGrid::generateNormals() &lt;br /&gt;
{&lt;br /&gt;
	_normals = new float[_numVertices * 3];&lt;br /&gt;
	for (int i=0; i&amp;lt; _numVertices*3; i+=3) {&lt;br /&gt;
		int pos = i/3;&lt;br /&gt;
		int xPos = pos % _gridSize;&lt;br /&gt;
		int yPos = pos / _gridSize;&lt;br /&gt;
		Vec3f xPred;&lt;br /&gt;
		Vec3f xSucc;&lt;br /&gt;
		Vec3f yPred;&lt;br /&gt;
		Vec3f ySucc;&lt;br /&gt;
		Vec3f normal;&lt;br /&gt;
		if (xPos &amp;gt; 0 &amp;amp;&amp;amp; yPos &amp;gt; 0) {&lt;br /&gt;
			// if the current vertex is inside the grid we will calculate&lt;br /&gt;
			// two normals from the previous&amp;amp;next point and our current vertex&lt;br /&gt;
			if (xPos &amp;lt; _gridSize-1 &amp;amp;&amp;amp; yPos &amp;lt; _gridSize-1) {&lt;br /&gt;
				xSucc = _grid[yPos][xPos+1];&lt;br /&gt;
				xPred = _grid[yPos][xPos-1];&lt;br /&gt;
				ySucc = _grid[yPos+1][xPos];&lt;br /&gt;
				yPred = _grid[yPos-1][xPos];&lt;br /&gt;
				Vec3f v1 = xSucc - _grid[yPos][xPos];&lt;br /&gt;
				if (v1.y &amp;lt; 0)&lt;br /&gt;
					v1.y *= -1;&lt;br /&gt;
				Vec3f v2 = xPred - _grid[yPos][xPos];&lt;br /&gt;
				if (v2.y &amp;lt; 0)&lt;br /&gt;
					v2.y *= -1;&lt;br /&gt;
				v1 += v2;&lt;br /&gt;
				Vec3f v3 = ySucc - _grid[yPos][xPos];&lt;br /&gt;
				if (v3.y &amp;lt; 0)&lt;br /&gt;
					v3.y *= -1;&lt;br /&gt;
				Vec3f v4 = yPred - _grid[yPos][xPos];&lt;br /&gt;
				if (v4.y &amp;lt; 0)&lt;br /&gt;
					v4.y *= -1;&lt;br /&gt;
				v3 += v4;&lt;br /&gt;
				normal = getInterpolatedNormal(v1, v3);&lt;br /&gt;
			}&lt;br /&gt;
			// if the vertex is on the grid's border the normal will simply be 0/1/0&lt;br /&gt;
			else {&lt;br /&gt;
				normal = Vec3f(0,1,0);&lt;br /&gt;
			}&lt;br /&gt;
		}&lt;br /&gt;
		else {&lt;br /&gt;
			normal = Vec3f(0,1,0);&lt;br /&gt;
		}&lt;br /&gt;
		_normals[i] = normal.x;&lt;br /&gt;
		_normals[i+1] = normal.y;&lt;br /&gt;
		_normals[i+2] = normal.z;&lt;br /&gt;
	}&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void DynamicGrid::generateTexCoords()&lt;br /&gt;
{&lt;br /&gt;
	_texCoords = new float[_numVertices * 2];&lt;br /&gt;
	int counter = 0;&lt;br /&gt;
	int line = 0;&lt;br /&gt;
	for (int i=0; i&amp;lt;_numVertices*2; i+=2) {&lt;br /&gt;
		if ( line % 2 == 0) {&lt;br /&gt;
			if (counter %2 == 0) {&lt;br /&gt;
				_texCoords[i] = 0.0f;&lt;br /&gt;
				_texCoords[i+1] = 0.0f;&lt;br /&gt;
			}&lt;br /&gt;
			else {&lt;br /&gt;
				_texCoords[i] = 0.0f;&lt;br /&gt;
				_texCoords[i+1] = 1.0f;&lt;br /&gt;
			}&lt;br /&gt;
		}&lt;br /&gt;
		else {&lt;br /&gt;
			if (counter % 2 == 0) {&lt;br /&gt;
				_texCoords[i] = 1.0f;&lt;br /&gt;
				_texCoords[i+1] = 0.0f;&lt;br /&gt;
			}&lt;br /&gt;
			else {&lt;br /&gt;
				_texCoords[i] = 1.0f;&lt;br /&gt;
				_texCoords[i+1] = 1.0f;&lt;br /&gt;
			}&lt;br /&gt;
		}&lt;br /&gt;
		++counter;&lt;br /&gt;
		if (counter &amp;gt;= _gridSize) {&lt;br /&gt;
			++line;&lt;br /&gt;
			counter = 0;&lt;br /&gt;
		}&lt;br /&gt;
	}&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void DynamicGrid::generateTriangleIndices() &lt;br /&gt;
{&lt;br /&gt;
	_tIndices = new int[ _numTriangleIndices ];&lt;br /&gt;
	int counter = 0;&lt;br /&gt;
	int lineBreakCounter = 0;&lt;br /&gt;
	int counter3 = 0;&lt;br /&gt;
	for (int i=0; i&amp;lt;_numTriangleIndices; i+=3) {&lt;br /&gt;
		if (i%2 ==0) {&lt;br /&gt;
			_tIndices[i] = counter;&lt;br /&gt;
			_tIndices[i+1] = counter+1;&lt;br /&gt;
			_tIndices[i+2] = counter+_gridSize;&lt;br /&gt;
		}&lt;br /&gt;
		else {&lt;br /&gt;
			_tIndices[i] = counter + _gridSize;&lt;br /&gt;
			_tIndices[i+1] = counter + 1;&lt;br /&gt;
			_tIndices[i+2] = counter+_gridSize+1;&lt;br /&gt;
			++counter;&lt;br /&gt;
		}&lt;br /&gt;
		++lineBreakCounter;&lt;br /&gt;
		if (lineBreakCounter == _gridSize*2 - 2) {&lt;br /&gt;
			--counter;&lt;br /&gt;
			++counter3;&lt;br /&gt;
			lineBreakCounter = 0;&lt;br /&gt;
			counter = counter3*_gridSize;&lt;br /&gt;
		}&lt;br /&gt;
		//std::cout&amp;lt;&amp;lt;_tIndices[i]&amp;lt;&amp;lt;&amp;quot;/&amp;quot;&amp;lt;&amp;lt;_tIndices[i+1]&amp;lt;&amp;lt;&amp;quot;/&amp;quot;&amp;lt;&amp;lt;_tIndices[i+2]&amp;lt;&amp;lt;std::endl;&lt;br /&gt;
	}&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void DynamicGrid::update()&lt;br /&gt;
{&lt;br /&gt;
	removeCustomModelNode();&lt;br /&gt;
	delete[] _positions;&lt;br /&gt;
	_positions = 0;&lt;br /&gt;
	delete[] _normals;&lt;br /&gt;
	_normals = 0;&lt;br /&gt;
	generatePositions();&lt;br /&gt;
	generateNormals();&lt;br /&gt;
	addCustomModelNode(-1);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void DynamicGrid::saveGridToFile(std::string fileName_)&lt;br /&gt;
{&lt;br /&gt;
	//std::stringstream fName;&lt;br /&gt;
	//fName&amp;lt;&amp;lt;fileName_;&lt;br /&gt;
	//fName&amp;lt;&amp;lt;&amp;quot;.d2g&amp;quot;;&lt;br /&gt;
	std::stringstream ss;&lt;br /&gt;
	// magic header&lt;br /&gt;
	ss&amp;lt;&amp;lt;&amp;quot;D2SG\n&amp;quot;;&lt;br /&gt;
	// the gridsize (important to know!)&lt;br /&gt;
	ss&amp;lt;&amp;lt;_gridSize;&lt;br /&gt;
	ss&amp;lt;&amp;lt;&amp;quot;\n&amp;quot;;&lt;br /&gt;
	// the quadsize (important to know!)&lt;br /&gt;
	ss&amp;lt;&amp;lt;_size;&lt;br /&gt;
	ss&amp;lt;&amp;lt;&amp;quot;\n&amp;quot;;&lt;br /&gt;
	// number of coordinates (most important to know!)&lt;br /&gt;
	ss&amp;lt;&amp;lt;(_gridSize*_gridSize*3);&lt;br /&gt;
	ss&amp;lt;&amp;lt;&amp;quot;\n&amp;quot;;&lt;br /&gt;
	// coordinates&lt;br /&gt;
	for (int y=0; y&amp;lt;_gridSize; ++y) {&lt;br /&gt;
		for (int x=0; x&amp;lt;_gridSize; ++x) {&lt;br /&gt;
			ss&amp;lt;&amp;lt;_grid[y][x].x;&lt;br /&gt;
			ss&amp;lt;&amp;lt;&amp;quot;\n&amp;quot;;&lt;br /&gt;
			ss&amp;lt;&amp;lt;_grid[y][x].y;&lt;br /&gt;
			ss&amp;lt;&amp;lt;&amp;quot;\n&amp;quot;;&lt;br /&gt;
			ss&amp;lt;&amp;lt;_grid[y][x].z;&lt;br /&gt;
			ss&amp;lt;&amp;lt;&amp;quot;\n&amp;quot;;&lt;br /&gt;
		}&lt;br /&gt;
	}&lt;br /&gt;
	ss&amp;lt;&amp;lt;&amp;quot;\n&amp;quot;;&lt;br /&gt;
	std::ofstream dest(fileName_.c_str());&lt;br /&gt;
	if (dest.is_open()) {&lt;br /&gt;
		dest&amp;lt;&amp;lt;ss.str();&lt;br /&gt;
		dest.close();&lt;br /&gt;
	}&lt;br /&gt;
	std::cout&amp;lt;&amp;lt;&amp;quot;Grid successfully saved to file: &amp;quot;&amp;lt;&amp;lt;fileName_&amp;lt;&amp;lt;std::endl;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
bool DynamicGrid::readGridFromFile(std::string fileName_)&lt;br /&gt;
{&lt;br /&gt;
	int numCoordinates;&lt;br /&gt;
	std::ifstream inFile;&lt;br /&gt;
	inFile.open(fileName_.c_str());&lt;br /&gt;
	bool error = false;&lt;br /&gt;
	if (!inFile) {&lt;br /&gt;
		std::cout&amp;lt;&amp;lt;&amp;quot;Gridfile &amp;quot;&amp;lt;&amp;lt;fileName_&amp;lt;&amp;lt;&amp;quot; could not be found! Creating new grid.&amp;quot;&amp;lt;&amp;lt;std::endl;&lt;br /&gt;
		error = true;&lt;br /&gt;
	}&lt;br /&gt;
	else {&lt;br /&gt;
		std::string line;&lt;br /&gt;
		if (std::getline(inFile, line)) {&lt;br /&gt;
			std::cout&amp;lt;&amp;lt;&amp;quot;Line: &amp;quot;&amp;lt;&amp;lt;line&amp;lt;&amp;lt;std::endl;&lt;br /&gt;
			//if (!(line == &amp;quot;D2SG&amp;quot;)) {&lt;br /&gt;
			if (line.compare(&amp;quot;D2SG&amp;quot;) != 0){&lt;br /&gt;
				std::cout&amp;lt;&amp;lt;&amp;quot;wrong grid-file format &amp;quot;&amp;lt;&amp;lt;line.compare(&amp;quot;D2SG&amp;quot;)&amp;lt;&amp;lt;std::endl;&lt;br /&gt;
				error = true;&lt;br /&gt;
			}&lt;br /&gt;
			else {&lt;br /&gt;
				std::cout&amp;lt;&amp;lt;&amp;quot;Valid grid-file found!&amp;quot;&amp;lt;&amp;lt;std::endl;&lt;br /&gt;
			}&lt;br /&gt;
		}&lt;br /&gt;
		if (std::getline(inFile, line)) {&lt;br /&gt;
			_gridSize = stringToInt(line);&lt;br /&gt;
			//std::cout&amp;lt;&amp;lt;&amp;quot;gridsize: &amp;quot;&amp;lt;&amp;lt;_gridSize&amp;lt;&amp;lt;std::endl;&lt;br /&gt;
		}&lt;br /&gt;
		else {&lt;br /&gt;
			error = true;&lt;br /&gt;
		}&lt;br /&gt;
		if (std::getline(inFile, line)) {&lt;br /&gt;
			_size = stringToInt(line);&lt;br /&gt;
			//std::cout&amp;lt;&amp;lt;&amp;quot;quadsize: &amp;quot;&amp;lt;&amp;lt;_size&amp;lt;&amp;lt;std::endl;&lt;br /&gt;
		}&lt;br /&gt;
		else {&lt;br /&gt;
			error = true;&lt;br /&gt;
		}&lt;br /&gt;
		if (std::getline(inFile, line)) {&lt;br /&gt;
			numCoordinates = stringToInt(line);&lt;br /&gt;
			//std::cout&amp;lt;&amp;lt;&amp;quot;numCoords: &amp;quot;&amp;lt;&amp;lt;numCoordinates&amp;lt;&amp;lt;std::endl;&lt;br /&gt;
		}&lt;br /&gt;
		else {&lt;br /&gt;
			error = true;&lt;br /&gt;
		}&lt;br /&gt;
		if (!error) {&lt;br /&gt;
			_grid = new Vec3f*[_gridSize];&lt;br /&gt;
			for(int y=0; y&amp;lt;_gridSize; ++y) {&lt;br /&gt;
				_grid[y] = new Vec3f[_gridSize];&lt;br /&gt;
				for (int x=0; x&amp;lt;_gridSize; ++x) {&lt;br /&gt;
					Vec3f v;&lt;br /&gt;
					if (std::getline(inFile, line)) {&lt;br /&gt;
						v.x = stringToFloat(line);&lt;br /&gt;
					}&lt;br /&gt;
					if (std::getline(inFile, line)) {&lt;br /&gt;
						v.y = stringToFloat(line);&lt;br /&gt;
					}&lt;br /&gt;
					if (std::getline(inFile, line)) {&lt;br /&gt;
						v.z = stringToFloat(line);&lt;br /&gt;
					}&lt;br /&gt;
					_grid[y][x] = v;&lt;br /&gt;
				}&lt;br /&gt;
			}&lt;br /&gt;
		}&lt;br /&gt;
	}&lt;br /&gt;
	inFile.close();&lt;br /&gt;
	if (error) {&lt;br /&gt;
		_gridSize = GRIDSIZE;&lt;br /&gt;
		_size = 12;&lt;br /&gt;
		_grid = 0;&lt;br /&gt;
	}&lt;br /&gt;
	_numVertices = (_gridSize*_gridSize);&lt;br /&gt;
	_numTriangles = ((_gridSize - 1) * (_gridSize - 1)) * 2;&lt;br /&gt;
	_numTriangleIndices = _numTriangles * 3;&lt;br /&gt;
	_origin = Vec3f(-_size/2*_gridSize, 0, _size/2*_gridSize);&lt;br /&gt;
	return true;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
=Usage example=&lt;br /&gt;
&lt;br /&gt;
Finally this is all you have to do to generate the grid and display it in your scene.&lt;br /&gt;
{{CppSourceCode|&lt;br /&gt;
description= app.cpp| &lt;br /&gt;
code=&lt;br /&gt;
&amp;lt;source lang=&amp;quot;cpp&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
	// initialize a new grid (args: quadsize, model-name, filename (if applicable)&lt;br /&gt;
	_grid = new DynamicGrid(12.0f, &amp;quot;grid&amp;quot;, &amp;quot;grid-filename&amp;quot;);&lt;br /&gt;
	// do not forget to load a material and apply it to the mesh&lt;br /&gt;
	_grid-&amp;gt;setMaterial(gridMatRes);&lt;br /&gt;
	// generate the grid&lt;br /&gt;
	_grid-&amp;gt;generate();&lt;br /&gt;
	// add the grid-model to the RootNode&lt;br /&gt;
	_grid-&amp;gt;addCustomModelNode(RootNode);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
'''TODO'''&lt;br /&gt;
}}&lt;/div&gt;</summary>
		<author><name>Wakko</name></author>	</entry>

	<entry>
		<id>http://horde3d.org/wiki/index.php?title=Procedurally_generated_geometry_tutorial&amp;diff=595</id>
		<title>Procedurally generated geometry tutorial</title>
		<link rel="alternate" type="text/html" href="http://horde3d.org/wiki/index.php?title=Procedurally_generated_geometry_tutorial&amp;diff=595"/>
				<updated>2009-11-28T13:34:22Z</updated>
		
		<summary type="html">&lt;p&gt;Wakko: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;'''Work in progress   - Due to the current changes in the Horde API this tutorial will be delayed '''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
= Important notes=&lt;br /&gt;
* The code used here has been tested with Horde3D 1.0.0 beta2 and beta3 and will '''NOT''' work with the latest release (beta4)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=Overview=&lt;br /&gt;
==Basic approach==&lt;br /&gt;
To create and display a procedurally generated mesh that, instead of being loaded from a Horde3D Scene node and a geoemtry file(*.scene.xml, *.geo), will be created in-memory by some algorithm, you have to create a mesh first and then &amp;quot;fake&amp;quot; the .geo-file and the scene node itself and pass it to the engine.&lt;br /&gt;
&lt;br /&gt;
To do that you have to create your procedural geometry first. This is easy for simple shapes like single triangles, squares or triangle-strips, but will become way more difficult when we try to generate complex meshes, e.g. when we have a cloud of points in 3D space and have to describe which points make triangles, and which don't (calculating the triangle indices, texture coordinates and normals).&lt;br /&gt;
&lt;br /&gt;
When we have calculated the geometry itself we need to create a char-stream to make Horde believe the geometry has been read from a file and pass it to Horde as a geometry Resource.&lt;br /&gt;
The final step is to create a Horde3D Scene Node from our procedurally generated mesh and render it into our scene.&lt;br /&gt;
[http://musicracer.de/images/Screenshot-1_small.jpg &lt;br /&gt;
This is how it could look like]&lt;br /&gt;
&lt;br /&gt;
=StreamGenerator=&lt;br /&gt;
&lt;br /&gt;
These classes are only for creating the character stream that will contain the geometry resource.&lt;br /&gt;
&lt;br /&gt;
{{CppSourceCode|&lt;br /&gt;
description= StreamGenerator.h| &lt;br /&gt;
code=&lt;br /&gt;
&amp;lt;source lang=&amp;quot;cpp&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
#pragma once&lt;br /&gt;
#include &amp;lt;sstream&amp;gt;&lt;br /&gt;
#include &amp;lt;string&amp;gt;&lt;br /&gt;
#include &amp;lt;iostream&amp;gt;&lt;br /&gt;
&lt;br /&gt;
class StreamGenerator &lt;br /&gt;
{&lt;br /&gt;
public:&lt;br /&gt;
	StreamGenerator();&lt;br /&gt;
	virtual ~StreamGenerator();&lt;br /&gt;
	virtual const char* getStream() = 0;&lt;br /&gt;
	virtual const int getStreamSize() = 0;&lt;br /&gt;
};&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{CppSourceCode|&lt;br /&gt;
description= StreamGenerator.cpp| &lt;br /&gt;
code=&lt;br /&gt;
&amp;lt;source lang=&amp;quot;cpp&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;quot;StreamGenerator.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
StreamGenerator::StreamGenerator() &lt;br /&gt;
{&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
StreamGenerator::~StreamGenerator()&lt;br /&gt;
{&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{CppSourceCode|&lt;br /&gt;
description= GeometryStreamGenerator.h| &lt;br /&gt;
code=&lt;br /&gt;
&amp;lt;source lang=&amp;quot;cpp&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
#pragma once&lt;br /&gt;
#include &amp;quot;StreamGenerator.h&amp;quot;&lt;br /&gt;
#include &amp;quot;CustomGeometry.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
class GeometryStreamGenerator : public StreamGenerator&lt;br /&gt;
{&lt;br /&gt;
private:&lt;br /&gt;
	std::stringstream* ss;&lt;br /&gt;
	void generate();&lt;br /&gt;
	int numVertices, numTriangleIndices;&lt;br /&gt;
	char* _stream;&lt;br /&gt;
	CustomGeometry* _geom;&lt;br /&gt;
&lt;br /&gt;
public:&lt;br /&gt;
	GeometryStreamGenerator(CustomGeometry* geom_);&lt;br /&gt;
	~GeometryStreamGenerator();&lt;br /&gt;
	const char* getStream();&lt;br /&gt;
	const std::stringstream* getStringStream() { return ss; };&lt;br /&gt;
	const int getStreamSize();&lt;br /&gt;
	const int getNumVertices();&lt;br /&gt;
	const int getNumTriangleIndices();&lt;br /&gt;
	void release();&lt;br /&gt;
};&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{CppSourceCode|&lt;br /&gt;
description= GeometryStreamGenerator.cpp| &lt;br /&gt;
code=&lt;br /&gt;
&amp;lt;source lang=&amp;quot;cpp&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;quot;GeometryStreamGenerator.h&amp;quot;&lt;br /&gt;
#include &amp;quot;time.h&amp;quot;&lt;br /&gt;
#include &amp;quot;utMath.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
GeometryStreamGenerator::GeometryStreamGenerator(CustomGeometry* geom_) : _geom(geom_)&lt;br /&gt;
{&lt;br /&gt;
	ss = new std::stringstream();&lt;br /&gt;
	generate();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
GeometryStreamGenerator::~GeometryStreamGenerator()&lt;br /&gt;
{&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void GeometryStreamGenerator::generate()&lt;br /&gt;
{&lt;br /&gt;
	numVertices = _geom-&amp;gt;getNumVertices();&lt;br /&gt;
	numTriangleIndices = _geom-&amp;gt;getNumTriangleIndices();&lt;br /&gt;
	const std::string _magicHeader = &amp;quot;H3DG&amp;quot;;&lt;br /&gt;
	const int _version = 5;&lt;br /&gt;
	const int _numJoints = 1;&lt;br /&gt;
	const float _identityMatrix[] = {	1.0f, 0.0f, 0.0f, 0.0f,  &lt;br /&gt;
						0.0f, 1.0f, 0.0f, 0.0f,  &lt;br /&gt;
						0.0f, 0.0f, 1.0f, 0.0f,  &lt;br /&gt;
						0.0f, 0.0f, 0.0f, 1.0f};&lt;br /&gt;
	const int _numVertexStreams = 3;&lt;br /&gt;
	const int _magicVertices = 0;&lt;br /&gt;
	const int _vertexStreamElementSize = 12;&lt;br /&gt;
	const float* _positions = _geom-&amp;gt;getPositions();&lt;br /&gt;
	const int _magicNormals = 1;&lt;br /&gt;
	const int _normalsStreamElementSize = 6;&lt;br /&gt;
	const float* _normals = _geom-&amp;gt;getNormals();&lt;br /&gt;
	const int _magicTextureCoords1 = 6;&lt;br /&gt;
	const int _texCoordStreamElementSize = 8;&lt;br /&gt;
	const float* _texCoords = _geom-&amp;gt;getTexCoords();&lt;br /&gt;
	const int* _triangleIndices = _geom-&amp;gt;getTriangleIndices();&lt;br /&gt;
	const int _numMorphTragets = 0;&lt;br /&gt;
	// header&lt;br /&gt;
	ss-&amp;gt;write(_magicHeader.c_str(), 4*sizeof(char));&lt;br /&gt;
	ss-&amp;gt;write((char*)&amp;amp;_version, sizeof(int));&lt;br /&gt;
	// joints (mandatory)&lt;br /&gt;
	ss-&amp;gt;write((char*)&amp;amp;_numJoints, sizeof(int));&lt;br /&gt;
	for (int i=0; i&amp;lt;16; ++i) {&lt;br /&gt;
		ss-&amp;gt;write((char*)&amp;amp;_identityMatrix[i], sizeof(float));&lt;br /&gt;
	}&lt;br /&gt;
	// vertices&lt;br /&gt;
	ss-&amp;gt;write((char*)&amp;amp;_numVertexStreams, sizeof(int));&lt;br /&gt;
	const int numVerts = _geom-&amp;gt;getNumVertices();&lt;br /&gt;
	ss-&amp;gt;write((char*)&amp;amp;numVerts, sizeof(int));&lt;br /&gt;
	ss-&amp;gt;write((char*)&amp;amp;_magicVertices, sizeof(int));&lt;br /&gt;
	ss-&amp;gt;write((char*)&amp;amp;_vertexStreamElementSize, sizeof(int));&lt;br /&gt;
	for (int i=0; i&amp;lt;_geom-&amp;gt;getNumVertices()*3; ++i) {&lt;br /&gt;
		ss-&amp;gt;write((char*)&amp;amp;_positions[i], sizeof(float));&lt;br /&gt;
	}&lt;br /&gt;
	// normals&lt;br /&gt;
	ss-&amp;gt;write((char*)&amp;amp;_magicNormals, sizeof(int));&lt;br /&gt;
	ss-&amp;gt;write((char*)&amp;amp;_normalsStreamElementSize, sizeof(int));&lt;br /&gt;
	for (int i=0; i&amp;lt;_geom-&amp;gt;getNumVertices()*3; ++i) {&lt;br /&gt;
		// do not forget to mutliply the value with 32767 and &lt;br /&gt;
		// then convert it to short before writing to the stream&lt;br /&gt;
		const short f = (short)(_normals[i]*32767);&lt;br /&gt;
		ss-&amp;gt;write((char*)&amp;amp;f, sizeof(short));&lt;br /&gt;
	}&lt;br /&gt;
	// texture coordinates&lt;br /&gt;
	ss-&amp;gt;write((char*)&amp;amp;_magicTextureCoords1, sizeof(int));&lt;br /&gt;
	ss-&amp;gt;write((char*)&amp;amp;_texCoordStreamElementSize, sizeof(int));&lt;br /&gt;
	for (int i=0; i&amp;lt;_geom-&amp;gt;getNumVertices()*2; ++i) {&lt;br /&gt;
		ss-&amp;gt;write((char*)&amp;amp;_texCoords[i], sizeof(float));&lt;br /&gt;
	}&lt;br /&gt;
	// triangle indices&lt;br /&gt;
	const int numTriangleIndices = _geom-&amp;gt;getNumTriangleIndices();&lt;br /&gt;
	ss-&amp;gt;write((char*)&amp;amp;numTriangleIndices, sizeof(int));&lt;br /&gt;
	for (int i=0; i&amp;lt;_geom-&amp;gt;getNumTriangleIndices(); ++i) {&lt;br /&gt;
		ss-&amp;gt;write((char*)&amp;amp;_triangleIndices[i], sizeof(int));&lt;br /&gt;
	}&lt;br /&gt;
	ss-&amp;gt;write((char*)&amp;amp;_numMorphTragets, sizeof(int));&lt;br /&gt;
	_stream = new char[ss-&amp;gt;tellp()];&lt;br /&gt;
	ss-&amp;gt;read(_stream, ss-&amp;gt;tellp());&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
const char* GeometryStreamGenerator::getStream()&lt;br /&gt;
{&lt;br /&gt;
	return _stream;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
const int GeometryStreamGenerator::getStreamSize() &lt;br /&gt;
{&lt;br /&gt;
	int t = (int)ss-&amp;gt;tellp();&lt;br /&gt;
	return t;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
const int GeometryStreamGenerator::getNumVertices()&lt;br /&gt;
{&lt;br /&gt;
	return numVertices;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
const int GeometryStreamGenerator::getNumTriangleIndices()&lt;br /&gt;
{&lt;br /&gt;
	return numTriangleIndices;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void GeometryStreamGenerator::release()&lt;br /&gt;
{&lt;br /&gt;
	ss-&amp;gt;flush();&lt;br /&gt;
	ss-&amp;gt;clear();&lt;br /&gt;
	delete ss;&lt;br /&gt;
	ss = 0;&lt;br /&gt;
	delete[] _stream;&lt;br /&gt;
	_stream = 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
=CustomGeometry base class=&lt;br /&gt;
&lt;br /&gt;
Base class for the custom geometry. This class currently contains lots of deprecated stuff, e.g. the update() function. This function was used to update an in-memory gemoetry resource in the &amp;quot;punk-rock&amp;quot;-way. Until Horde3D Beta3 the geometry resources were read-only, so directmanipulation of vertices was impossible. To modify the vertices I had to unload the geometry resource, re-create it with the new vertex-positions and load it into Horde again. '''This is not necessary any more because since Beta4 the geometry resources are not read-only anymore.'''&lt;br /&gt;
&lt;br /&gt;
All custom geometry classes should be derived from this class and implement the abstract functions as needed. (See the examples below)&lt;br /&gt;
&lt;br /&gt;
{{CppSourceCode|&lt;br /&gt;
description= CustomGeometry.h| &lt;br /&gt;
code=&lt;br /&gt;
&amp;lt;source lang=&amp;quot;cpp&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
#pragma once&lt;br /&gt;
/**&lt;br /&gt;
 * Abstract class for custom/dynamic geometry&lt;br /&gt;
 **/&lt;br /&gt;
#include &amp;quot;utMath.h&amp;quot;&lt;br /&gt;
#include &amp;quot;Horde3D.h&amp;quot;&lt;br /&gt;
#include &amp;lt;string&amp;gt;&lt;br /&gt;
&lt;br /&gt;
class CustomGeometry &lt;br /&gt;
{&lt;br /&gt;
protected:&lt;br /&gt;
	float _size;&lt;br /&gt;
	Vec3f _origin;&lt;br /&gt;
	int _numVertices;&lt;br /&gt;
	int _numTriangles;&lt;br /&gt;
	int _numTriangleIndices;&lt;br /&gt;
	float* _positions;&lt;br /&gt;
	float* _normals;&lt;br /&gt;
	float* _texCoords;&lt;br /&gt;
	int* _tIndices;&lt;br /&gt;
	std::string _name;&lt;br /&gt;
	NodeHandle _model;&lt;br /&gt;
	NodeHandle _parent;&lt;br /&gt;
	ResHandle _material;&lt;br /&gt;
	virtual void generatePositions() = 0;&lt;br /&gt;
	virtual void generateNormals() = 0;&lt;br /&gt;
	virtual void generateTexCoords() = 0;&lt;br /&gt;
	virtual void generateTriangleIndices() = 0;&lt;br /&gt;
&lt;br /&gt;
public:&lt;br /&gt;
	CustomGeometry();&lt;br /&gt;
	virtual void generate() = 0;&lt;br /&gt;
	const int getNumVertices() { return _numVertices; }&lt;br /&gt;
	const float* getPositions() { return _positions; }&lt;br /&gt;
	const float* getNormals() { return _normals; }&lt;br /&gt;
	const float* getTexCoords() { return _texCoords; }&lt;br /&gt;
	const int* getTriangleIndices() { return _tIndices; }&lt;br /&gt;
	const int getNumTriangles() { return _numTriangles; }&lt;br /&gt;
	const int getNumTriangleIndices() { return _numTriangleIndices; }&lt;br /&gt;
	void release();&lt;br /&gt;
	const Vec3f getInterpolatedNormal(Vec3f n1_, Vec3f n2_);&lt;br /&gt;
	// pass -1 as the parameter to leave the parent node unchanged&lt;br /&gt;
	void addCustomModelNode(NodeHandle parent_);&lt;br /&gt;
	bool removeCustomModelNode();&lt;br /&gt;
	void setMaterial(ResHandle material_) { _material = material_; }&lt;br /&gt;
	void setParent(NodeHandle parent_) { _parent = parent_; }&lt;br /&gt;
	NodeHandle getModel() { return _model; }&lt;br /&gt;
	ResHandle getMaterial() { return _material; }&lt;br /&gt;
	void update();&lt;br /&gt;
	Vec3f getOrigin() { return _origin; }&lt;br /&gt;
	void setOrigin(Vec3f origin_) { _origin = origin_; }&lt;br /&gt;
	const float getSize() { return _size; }&lt;br /&gt;
};&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{CppSourceCode|&lt;br /&gt;
description= CustomGeometry.cpp| &lt;br /&gt;
code=&lt;br /&gt;
&amp;lt;source lang=&amp;quot;cpp&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;quot;CustomGeometry.h&amp;quot;&lt;br /&gt;
#include &amp;lt;iostream&amp;gt;&lt;br /&gt;
#include &amp;lt;string&amp;gt;&lt;br /&gt;
#include &amp;lt;sstream&amp;gt;&lt;br /&gt;
#include &amp;lt;fstream&amp;gt;&lt;br /&gt;
#include &amp;quot;GeometryStreamGenerator.h&amp;quot;&lt;br /&gt;
#include &amp;quot;Horde3DUtils.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
CustomGeometry::CustomGeometry() : _name(&amp;quot;default&amp;quot;), _size(1)&lt;br /&gt;
{&lt;br /&gt;
	_origin = Vec3f(0, 0, 0);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void CustomGeometry::release()&lt;br /&gt;
{&lt;br /&gt;
	delete[] _positions;&lt;br /&gt;
	_positions = 0;&lt;br /&gt;
	delete[] _normals;&lt;br /&gt;
	_normals = 0;&lt;br /&gt;
	delete[] _texCoords;&lt;br /&gt;
	_texCoords = 0;&lt;br /&gt;
	delete[] _tIndices;&lt;br /&gt;
	_tIndices = 0;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
const Vec3f CustomGeometry::getInterpolatedNormal(Vec3f n1_, Vec3f n2_) &lt;br /&gt;
{&lt;br /&gt;
	Vec3f newNormal = n1_ + n2_;&lt;br /&gt;
	float length = newNormal.length();&lt;br /&gt;
	return newNormal/length;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void CustomGeometry::addCustomModelNode(NodeHandle parent_)&lt;br /&gt;
{&lt;br /&gt;
	//std::stringstream* sa = new std::stringstream();&lt;br /&gt;
	std::stringstream ss;&lt;br /&gt;
	if (parent_ != -1) &lt;br /&gt;
		_parent = parent_;&lt;br /&gt;
	ss&amp;lt;&amp;lt; &amp;quot;customGeometry-&amp;quot;;&lt;br /&gt;
	ss&amp;lt;&amp;lt;_name;&lt;br /&gt;
	GeometryStreamGenerator* gsg = new GeometryStreamGenerator(this);&lt;br /&gt;
	ResHandle customGeoRes = Horde3D::addResource(ResourceTypes::Geometry, ss.str().c_str(), 0);&lt;br /&gt;
	Horde3D::loadResource(customGeoRes, gsg-&amp;gt;getStream(), gsg-&amp;gt;getStreamSize());&lt;br /&gt;
	// model_node_name&lt;br /&gt;
	ss&amp;lt;&amp;lt;&amp;quot;-Node&amp;quot;;&lt;br /&gt;
	_model = Horde3D::addModelNode(_parent, ss.str().c_str(), customGeoRes);&lt;br /&gt;
	// mesh_name&lt;br /&gt;
	ss&amp;lt;&amp;lt;&amp;quot;-Mesh&amp;quot;;&lt;br /&gt;
	Horde3D::addMeshNode(_model, ss.str().c_str(), _material, 0, gsg-&amp;gt;getNumTriangleIndices(), 0, gsg-&amp;gt;getNumVertices()-1);&lt;br /&gt;
	Horde3DUtils::dumpMessages();&lt;br /&gt;
	ss.str(&amp;quot;&amp;quot;);&lt;br /&gt;
	ss.clear();&lt;br /&gt;
	ss.flush();&lt;br /&gt;
	gsg-&amp;gt;release();&lt;br /&gt;
	delete gsg;&lt;br /&gt;
	gsg = 0;&lt;br /&gt;
	//Horde3D::setNodeTransform(_model, _origin.x, _origin.y, _origin.z, 0, 0, 0, 1, 1, 1);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
bool CustomGeometry::removeCustomModelNode()&lt;br /&gt;
{&lt;br /&gt;
	std::stringstream* ss = new std::stringstream();&lt;br /&gt;
	*ss&amp;lt;&amp;lt; &amp;quot;customGeometry-&amp;quot;;&lt;br /&gt;
	*ss&amp;lt;&amp;lt;_name;&lt;br /&gt;
	ResHandle rh = Horde3D::findResource(ResourceTypes::Geometry, ss-&amp;gt;str().c_str());&lt;br /&gt;
	if (Horde3D::isResourceLoaded(rh)) {&lt;br /&gt;
		Horde3D::removeResource(rh);&lt;br /&gt;
		Horde3D::unloadResource(rh);&lt;br /&gt;
		Horde3D::removeNode(_model);&lt;br /&gt;
		Horde3D::releaseUnusedResources();&lt;br /&gt;
		Horde3DUtils::dumpMessages();&lt;br /&gt;
		delete ss;&lt;br /&gt;
		return true;&lt;br /&gt;
	}&lt;br /&gt;
	else &lt;br /&gt;
		return false;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void CustomGeometry::update()&lt;br /&gt;
{&lt;br /&gt;
	removeCustomModelNode();&lt;br /&gt;
	addCustomModelNode(-1);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
=Simple Square=&lt;br /&gt;
&lt;br /&gt;
A simple hard-coded square. This is pretty straight forward and demonstrates how to derive from the CustomGeometry class and how the triangle indices work.&lt;br /&gt;
&lt;br /&gt;
{{CppSourceCode|&lt;br /&gt;
description= DynamicSquare.h| &lt;br /&gt;
code=&lt;br /&gt;
&amp;lt;source lang=&amp;quot;cpp&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
/**&lt;br /&gt;
 * Class representing a square &lt;br /&gt;
 **/&lt;br /&gt;
#pragma once&lt;br /&gt;
#include &amp;quot;CustomGeometry.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
class DynamicSquare : public CustomGeometry&lt;br /&gt;
{&lt;br /&gt;
protected:&lt;br /&gt;
	virtual void generatePositions();&lt;br /&gt;
	virtual void generateNormals();&lt;br /&gt;
	virtual void generateTexCoords();&lt;br /&gt;
	virtual void generateTriangleIndices();&lt;br /&gt;
&lt;br /&gt;
public:&lt;br /&gt;
	DynamicSquare();&lt;br /&gt;
	virtual void generate();&lt;br /&gt;
	DynamicSquare(const float size_, const std::string name_);&lt;br /&gt;
};&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{CppSourceCode|&lt;br /&gt;
description= DynamicSquare.cpp| &lt;br /&gt;
code=&lt;br /&gt;
&amp;lt;source lang=&amp;quot;cpp&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;quot;DynamicSquare.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
DynamicSquare::DynamicSquare() : CustomGeometry()&lt;br /&gt;
{&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
DynamicSquare::DynamicSquare(const float size_, const std::string name_) &lt;br /&gt;
{&lt;br /&gt;
	_size = size_;&lt;br /&gt;
	_name = name_;&lt;br /&gt;
	_numVertices = 4;&lt;br /&gt;
	_numTriangles = 2;&lt;br /&gt;
	_numTriangleIndices = _numTriangles * 3;&lt;br /&gt;
	//generate();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void DynamicSquare::generate() &lt;br /&gt;
{&lt;br /&gt;
	generatePositions();&lt;br /&gt;
	generateNormals();&lt;br /&gt;
	generateTexCoords();&lt;br /&gt;
	generateTriangleIndices();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void DynamicSquare::generatePositions() &lt;br /&gt;
{&lt;br /&gt;
	_positions = new float[_numVertices * 3 * 2];&lt;br /&gt;
	// front left point (x/y/z)&lt;br /&gt;
	_positions[0] = _origin.x * _size - _size/2;&lt;br /&gt;
	_positions[1] = _origin.y;&lt;br /&gt;
	_positions[2] = _origin.z * _size -_size/2;&lt;br /&gt;
	// front right point (x/y/z)&lt;br /&gt;
	_positions[3] = _origin.x * _size + _size/2;&lt;br /&gt;
	_positions[4] = _origin.y;&lt;br /&gt;
	_positions[5] = _origin.z * _size - _size/2;&lt;br /&gt;
	// back left point (x/y/z)&lt;br /&gt;
	_positions[6] = _origin.x * _size - _size/2;&lt;br /&gt;
	_positions[7] = _origin.y;&lt;br /&gt;
	_positions[8] = _origin.z * _size + _size/2;&lt;br /&gt;
	// back right point (x/y/z)&lt;br /&gt;
	_positions[9] = _origin.x * _size + _size/2;&lt;br /&gt;
	_positions[10] = _origin.y;&lt;br /&gt;
	_positions[11] = _origin.z * _size + _size/2;&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void DynamicSquare::generateNormals() &lt;br /&gt;
{&lt;br /&gt;
	_normals = new float[_numVertices * 3];&lt;br /&gt;
	for (int i=0; i&amp;lt; 12; i+=3) {&lt;br /&gt;
		_normals[i] = 0;&lt;br /&gt;
		_normals[i+1] = 1;&lt;br /&gt;
		_normals[i+2] = 0;&lt;br /&gt;
	}&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void DynamicSquare::generateTexCoords()&lt;br /&gt;
{&lt;br /&gt;
	_texCoords = new float[_numVertices * 2];&lt;br /&gt;
	_texCoords[0] = 0.0f; &lt;br /&gt;
	_texCoords[1] = 0.0f;&lt;br /&gt;
	_texCoords[2] = 1.0f; &lt;br /&gt;
	_texCoords[3] = 0.0f;&lt;br /&gt;
	_texCoords[4] = 0.0f; &lt;br /&gt;
	_texCoords[5] = 1.0f;&lt;br /&gt;
	_texCoords[6] = 1.0f; &lt;br /&gt;
	_texCoords[7] = 1.0f;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void DynamicSquare::generateTriangleIndices() &lt;br /&gt;
{&lt;br /&gt;
	_tIndices = new int[_numTriangleIndices ];&lt;br /&gt;
	_tIndices[0] = 0;&lt;br /&gt;
	_tIndices[1] = 2;&lt;br /&gt;
	_tIndices[2] = 1;&lt;br /&gt;
	_tIndices[3] = 1;&lt;br /&gt;
	_tIndices[4] = 2;&lt;br /&gt;
	_tIndices[5] = 3;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
=Simple Grid=&lt;br /&gt;
&lt;br /&gt;
All the work above was made to create my own interactive terrain generator(screenshot on top of this page) for a A* pathfinding demonstrator. The Grid-class actually generates a 2-dimensional array of Vec3f(s) and allows to extrude each point and re-generate the mesh in realtime. The internal representation is writeable and in case of a change of any point the overridden update() function will be called to update the Horde3D geometry resource.&lt;br /&gt;
&lt;br /&gt;
[http://musicracer.de/images/grid_01_english.png&lt;br /&gt;
This is how it looks internally]&lt;br /&gt;
{{CppSourceCode|&lt;br /&gt;
description= DynamicGrid.h| &lt;br /&gt;
code=&lt;br /&gt;
&amp;lt;source lang=&amp;quot;cpp&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
/**&lt;br /&gt;
 * Class representing a grid&lt;br /&gt;
 **/&lt;br /&gt;
#pragma once&lt;br /&gt;
#include &amp;quot;CustomGeometry.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
class DynamicGrid : public CustomGeometry&lt;br /&gt;
{&lt;br /&gt;
protected:&lt;br /&gt;
	virtual void generatePositions();&lt;br /&gt;
	virtual void generateNormals();&lt;br /&gt;
	virtual void generateTexCoords();&lt;br /&gt;
	virtual void generateTriangleIndices();&lt;br /&gt;
       // generate the internal representation of the grid (writeable to allow updates of single points!)&lt;br /&gt;
	void generateGrid();&lt;br /&gt;
	int _gridSize;&lt;br /&gt;
	Vec3f** _grid;&lt;br /&gt;
	std::string _fileName;&lt;br /&gt;
&lt;br /&gt;
public:&lt;br /&gt;
	DynamicGrid();&lt;br /&gt;
	virtual void generate();&lt;br /&gt;
	DynamicGrid(const float size_, const std::string name_, std::string fileName_);&lt;br /&gt;
	Vec3f getPointAt(int x_, int y_) { return _grid[y_][x_]; }&lt;br /&gt;
	// update a point of our grid (args: index x, index y, new position)&lt;br /&gt;
	void setPointAt(int x_, int y_, Vec3f newPos_) { _grid[y_][x_] = newPos_; }&lt;br /&gt;
	int getGridSize() { return _gridSize; }&lt;br /&gt;
	// overwrite update() from parent class&lt;br /&gt;
	void update();&lt;br /&gt;
	// read and write grids from/to files&lt;br /&gt;
	void saveGridToFile(std::string fileName_);&lt;br /&gt;
	bool readGridFromFile(std::string fileName_);&lt;br /&gt;
&lt;br /&gt;
};&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{CppSourceCode|&lt;br /&gt;
description= DynamicGrid.cpp| &lt;br /&gt;
code=&lt;br /&gt;
&amp;lt;source lang=&amp;quot;cpp&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;quot;DynamicGrid.h&amp;quot;&lt;br /&gt;
#include &amp;quot;rng.h&amp;quot;&lt;br /&gt;
#include &amp;lt;iostream&amp;gt;&lt;br /&gt;
#include &amp;lt;string&amp;gt;&lt;br /&gt;
#include &amp;lt;sstream&amp;gt;&lt;br /&gt;
#include &amp;lt;fstream&amp;gt;&lt;br /&gt;
#include &amp;quot;util.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
#define GRIDSIZE 50&lt;br /&gt;
&lt;br /&gt;
DynamicGrid::DynamicGrid() : CustomGeometry()&lt;br /&gt;
{&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
DynamicGrid::DynamicGrid(const float size_, const std::string name_, std::string fileName_) : _fileName(fileName_) &lt;br /&gt;
{&lt;br /&gt;
	_name = name_;&lt;br /&gt;
	_positions = 0;&lt;br /&gt;
	_normals = 0;&lt;br /&gt;
	_texCoords = 0;&lt;br /&gt;
	_tIndices = 0;&lt;br /&gt;
	readGridFromFile(_fileName);&lt;br /&gt;
	_numVertices = (_gridSize*_gridSize);&lt;br /&gt;
	_numTriangles = ((_gridSize - 1) * (_gridSize - 1)) * 2;&lt;br /&gt;
	_numTriangleIndices = _numTriangles * 3;&lt;br /&gt;
	_origin = Vec3f(-_size/2*_gridSize, 0, _size/2*_gridSize);&lt;br /&gt;
	/*&lt;br /&gt;
	std::cout&amp;lt;&amp;lt;&amp;quot;numVerts: &amp;quot;&amp;lt;&amp;lt;_numVertices&amp;lt;&amp;lt;std::endl;&lt;br /&gt;
	std::cout&amp;lt;&amp;lt;&amp;quot;numTris: &amp;quot;&amp;lt;&amp;lt;_numTriangles&amp;lt;&amp;lt;std::endl;&lt;br /&gt;
	std::cout&amp;lt;&amp;lt;&amp;quot;numTInds: &amp;quot;&amp;lt;&amp;lt;_numTriangleIndices&amp;lt;&amp;lt;std::endl;&lt;br /&gt;
	std::cout&amp;lt;&amp;lt;&amp;quot;size: &amp;quot;&amp;lt;&amp;lt;_size&amp;lt;&amp;lt;std::endl;&lt;br /&gt;
	*/&lt;br /&gt;
	//std::cout&amp;lt;&amp;lt;_origin.x&amp;lt;&amp;lt;&amp;quot;/&amp;quot;&amp;lt;&amp;lt;_origin.y&amp;lt;&amp;lt;&amp;quot;/&amp;quot;&amp;lt;&amp;lt;_origin.z&amp;lt;&amp;lt;std::endl;&lt;br /&gt;
	//generate();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void DynamicGrid::generate() &lt;br /&gt;
{&lt;br /&gt;
	if (!_grid)&lt;br /&gt;
		generateGrid();&lt;br /&gt;
	generatePositions();&lt;br /&gt;
	generateNormals();&lt;br /&gt;
	generateTexCoords();&lt;br /&gt;
	generateTriangleIndices();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// the following two functions could be combined into one single loop, but I left it this way for clarity...&lt;br /&gt;
/**&lt;br /&gt;
 * This function simply generates a 2-dimensional array of Vec3f(s) with slightly random height values&lt;br /&gt;
 **/&lt;br /&gt;
void DynamicGrid::generateGrid()&lt;br /&gt;
{&lt;br /&gt;
	RNG rng;&lt;br /&gt;
	_grid = new Vec3f*[_gridSize];&lt;br /&gt;
	for (int y=0; y&amp;lt;_gridSize; ++y) {&lt;br /&gt;
		_grid[y] = new Vec3f[_gridSize];&lt;br /&gt;
		for (int x=0; x&amp;lt;_gridSize; ++x) {&lt;br /&gt;
			long rand = (abs((int)rng.rand_int31()) %3);&lt;br /&gt;
			_grid[y][x] = Vec3f(_origin.x/2+_size/2*x, rand, _origin.z/2-_size/2*y);&lt;br /&gt;
			//std::cout&amp;lt;&amp;lt;_grid[y][x].x&amp;lt;&amp;lt;&amp;quot;/&amp;quot;&amp;lt;&amp;lt;_grid[y][x].y&amp;lt;&amp;lt;&amp;quot;/&amp;quot;&amp;lt;&amp;lt;_grid[y][x].z&amp;lt;&amp;lt;std::endl;&lt;br /&gt;
		}&lt;br /&gt;
	}&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/**&lt;br /&gt;
 * Convert the grid's positions into a Horde3D vertex array.&lt;br /&gt;
 **/&lt;br /&gt;
void DynamicGrid::generatePositions() &lt;br /&gt;
{&lt;br /&gt;
	_positions = new float[_numVertices*3];&lt;br /&gt;
	int counter = 0;&lt;br /&gt;
	for (int i=0; i&amp;lt;_numVertices*3; i+=3) {&lt;br /&gt;
		int y = counter / _gridSize;&lt;br /&gt;
		int x = counter % _gridSize;&lt;br /&gt;
		_positions[i] = _grid[y][x].x;&lt;br /&gt;
		_positions[i+1] = _grid[y][x].y;&lt;br /&gt;
		_positions[i+2] = _grid[y][x].z;&lt;br /&gt;
		++counter;&lt;br /&gt;
	}&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void DynamicGrid::generateNormals() &lt;br /&gt;
{&lt;br /&gt;
	_normals = new float[_numVertices * 3];&lt;br /&gt;
	for (int i=0; i&amp;lt; _numVertices*3; i+=3) {&lt;br /&gt;
		int pos = i/3;&lt;br /&gt;
		int xPos = pos % _gridSize;&lt;br /&gt;
		int yPos = pos / _gridSize;&lt;br /&gt;
		Vec3f xPred;&lt;br /&gt;
		Vec3f xSucc;&lt;br /&gt;
		Vec3f yPred;&lt;br /&gt;
		Vec3f ySucc;&lt;br /&gt;
		Vec3f normal;&lt;br /&gt;
		if (xPos &amp;gt; 0 &amp;amp;&amp;amp; yPos &amp;gt; 0) {&lt;br /&gt;
			// if the current vertex is inside the grid we will calculate&lt;br /&gt;
			// two normals from the previous&amp;amp;next point and our current vertex&lt;br /&gt;
			if (xPos &amp;lt; _gridSize-1 &amp;amp;&amp;amp; yPos &amp;lt; _gridSize-1) {&lt;br /&gt;
				xSucc = _grid[yPos][xPos+1];&lt;br /&gt;
				xPred = _grid[yPos][xPos-1];&lt;br /&gt;
				ySucc = _grid[yPos+1][xPos];&lt;br /&gt;
				yPred = _grid[yPos-1][xPos];&lt;br /&gt;
				Vec3f v1 = xSucc - _grid[yPos][xPos];&lt;br /&gt;
				if (v1.y &amp;lt; 0)&lt;br /&gt;
					v1.y *= -1;&lt;br /&gt;
				Vec3f v2 = xPred - _grid[yPos][xPos];&lt;br /&gt;
				if (v2.y &amp;lt; 0)&lt;br /&gt;
					v2.y *= -1;&lt;br /&gt;
				v1 += v2;&lt;br /&gt;
				Vec3f v3 = ySucc - _grid[yPos][xPos];&lt;br /&gt;
				if (v3.y &amp;lt; 0)&lt;br /&gt;
					v3.y *= -1;&lt;br /&gt;
				Vec3f v4 = yPred - _grid[yPos][xPos];&lt;br /&gt;
				if (v4.y &amp;lt; 0)&lt;br /&gt;
					v4.y *= -1;&lt;br /&gt;
				v3 += v4;&lt;br /&gt;
				normal = getInterpolatedNormal(v1, v3);&lt;br /&gt;
			}&lt;br /&gt;
			// if the vertex is on the grid's border the normal will simply be 0/1/0&lt;br /&gt;
			else {&lt;br /&gt;
				normal = Vec3f(0,1,0);&lt;br /&gt;
			}&lt;br /&gt;
		}&lt;br /&gt;
		else {&lt;br /&gt;
			normal = Vec3f(0,1,0);&lt;br /&gt;
		}&lt;br /&gt;
		_normals[i] = normal.x;&lt;br /&gt;
		_normals[i+1] = normal.y;&lt;br /&gt;
		_normals[i+2] = normal.z;&lt;br /&gt;
	}&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void DynamicGrid::generateTexCoords()&lt;br /&gt;
{&lt;br /&gt;
	_texCoords = new float[_numVertices * 2];&lt;br /&gt;
	int counter = 0;&lt;br /&gt;
	int line = 0;&lt;br /&gt;
	for (int i=0; i&amp;lt;_numVertices*2; i+=2) {&lt;br /&gt;
		if ( line % 2 == 0) {&lt;br /&gt;
			if (counter %2 == 0) {&lt;br /&gt;
				_texCoords[i] = 0.0f;&lt;br /&gt;
				_texCoords[i+1] = 0.0f;&lt;br /&gt;
			}&lt;br /&gt;
			else {&lt;br /&gt;
				_texCoords[i] = 0.0f;&lt;br /&gt;
				_texCoords[i+1] = 1.0f;&lt;br /&gt;
			}&lt;br /&gt;
		}&lt;br /&gt;
		else {&lt;br /&gt;
			if (counter % 2 == 0) {&lt;br /&gt;
				_texCoords[i] = 1.0f;&lt;br /&gt;
				_texCoords[i+1] = 0.0f;&lt;br /&gt;
			}&lt;br /&gt;
			else {&lt;br /&gt;
				_texCoords[i] = 1.0f;&lt;br /&gt;
				_texCoords[i+1] = 1.0f;&lt;br /&gt;
			}&lt;br /&gt;
		}&lt;br /&gt;
		++counter;&lt;br /&gt;
		if (counter &amp;gt;= _gridSize) {&lt;br /&gt;
			++line;&lt;br /&gt;
			counter = 0;&lt;br /&gt;
		}&lt;br /&gt;
	}&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void DynamicGrid::generateTriangleIndices() &lt;br /&gt;
{&lt;br /&gt;
	_tIndices = new int[ _numTriangleIndices ];&lt;br /&gt;
	int counter = 0;&lt;br /&gt;
	int lineBreakCounter = 0;&lt;br /&gt;
	int counter3 = 0;&lt;br /&gt;
	for (int i=0; i&amp;lt;_numTriangleIndices; i+=3) {&lt;br /&gt;
		if (i%2 ==0) {&lt;br /&gt;
			_tIndices[i] = counter;&lt;br /&gt;
			_tIndices[i+1] = counter+1;&lt;br /&gt;
			_tIndices[i+2] = counter+_gridSize;&lt;br /&gt;
		}&lt;br /&gt;
		else {&lt;br /&gt;
			_tIndices[i] = counter + _gridSize;&lt;br /&gt;
			_tIndices[i+1] = counter + 1;&lt;br /&gt;
			_tIndices[i+2] = counter+_gridSize+1;&lt;br /&gt;
			++counter;&lt;br /&gt;
		}&lt;br /&gt;
		++lineBreakCounter;&lt;br /&gt;
		if (lineBreakCounter == _gridSize*2 - 2) {&lt;br /&gt;
			--counter;&lt;br /&gt;
			++counter3;&lt;br /&gt;
			lineBreakCounter = 0;&lt;br /&gt;
			counter = counter3*_gridSize;&lt;br /&gt;
		}&lt;br /&gt;
		//std::cout&amp;lt;&amp;lt;_tIndices[i]&amp;lt;&amp;lt;&amp;quot;/&amp;quot;&amp;lt;&amp;lt;_tIndices[i+1]&amp;lt;&amp;lt;&amp;quot;/&amp;quot;&amp;lt;&amp;lt;_tIndices[i+2]&amp;lt;&amp;lt;std::endl;&lt;br /&gt;
	}&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void DynamicGrid::update()&lt;br /&gt;
{&lt;br /&gt;
	removeCustomModelNode();&lt;br /&gt;
	delete[] _positions;&lt;br /&gt;
	_positions = 0;&lt;br /&gt;
	delete[] _normals;&lt;br /&gt;
	_normals = 0;&lt;br /&gt;
	generatePositions();&lt;br /&gt;
	generateNormals();&lt;br /&gt;
	addCustomModelNode(-1);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void DynamicGrid::saveGridToFile(std::string fileName_)&lt;br /&gt;
{&lt;br /&gt;
	//std::stringstream fName;&lt;br /&gt;
	//fName&amp;lt;&amp;lt;fileName_;&lt;br /&gt;
	//fName&amp;lt;&amp;lt;&amp;quot;.d2g&amp;quot;;&lt;br /&gt;
	std::stringstream ss;&lt;br /&gt;
	// magic header&lt;br /&gt;
	ss&amp;lt;&amp;lt;&amp;quot;D2SG\n&amp;quot;;&lt;br /&gt;
	// the gridsize (important to know!)&lt;br /&gt;
	ss&amp;lt;&amp;lt;_gridSize;&lt;br /&gt;
	ss&amp;lt;&amp;lt;&amp;quot;\n&amp;quot;;&lt;br /&gt;
	// the quadsize (important to know!)&lt;br /&gt;
	ss&amp;lt;&amp;lt;_size;&lt;br /&gt;
	ss&amp;lt;&amp;lt;&amp;quot;\n&amp;quot;;&lt;br /&gt;
	// number of coordinates (most important to know!)&lt;br /&gt;
	ss&amp;lt;&amp;lt;(_gridSize*_gridSize*3);&lt;br /&gt;
	ss&amp;lt;&amp;lt;&amp;quot;\n&amp;quot;;&lt;br /&gt;
	// coordinates&lt;br /&gt;
	for (int y=0; y&amp;lt;_gridSize; ++y) {&lt;br /&gt;
		for (int x=0; x&amp;lt;_gridSize; ++x) {&lt;br /&gt;
			ss&amp;lt;&amp;lt;_grid[y][x].x;&lt;br /&gt;
			ss&amp;lt;&amp;lt;&amp;quot;\n&amp;quot;;&lt;br /&gt;
			ss&amp;lt;&amp;lt;_grid[y][x].y;&lt;br /&gt;
			ss&amp;lt;&amp;lt;&amp;quot;\n&amp;quot;;&lt;br /&gt;
			ss&amp;lt;&amp;lt;_grid[y][x].z;&lt;br /&gt;
			ss&amp;lt;&amp;lt;&amp;quot;\n&amp;quot;;&lt;br /&gt;
		}&lt;br /&gt;
	}&lt;br /&gt;
	ss&amp;lt;&amp;lt;&amp;quot;\n&amp;quot;;&lt;br /&gt;
	std::ofstream dest(fileName_.c_str());&lt;br /&gt;
	if (dest.is_open()) {&lt;br /&gt;
		dest&amp;lt;&amp;lt;ss.str();&lt;br /&gt;
		dest.close();&lt;br /&gt;
	}&lt;br /&gt;
	std::cout&amp;lt;&amp;lt;&amp;quot;Grid successfully saved to file: &amp;quot;&amp;lt;&amp;lt;fileName_&amp;lt;&amp;lt;std::endl;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
bool DynamicGrid::readGridFromFile(std::string fileName_)&lt;br /&gt;
{&lt;br /&gt;
	int numCoordinates;&lt;br /&gt;
	std::ifstream inFile;&lt;br /&gt;
	inFile.open(fileName_.c_str());&lt;br /&gt;
	bool error = false;&lt;br /&gt;
	if (!inFile) {&lt;br /&gt;
		std::cout&amp;lt;&amp;lt;&amp;quot;Gridfile &amp;quot;&amp;lt;&amp;lt;fileName_&amp;lt;&amp;lt;&amp;quot; could not be found! Creating new grid.&amp;quot;&amp;lt;&amp;lt;std::endl;&lt;br /&gt;
		error = true;&lt;br /&gt;
	}&lt;br /&gt;
	else {&lt;br /&gt;
		std::string line;&lt;br /&gt;
		if (std::getline(inFile, line)) {&lt;br /&gt;
			std::cout&amp;lt;&amp;lt;&amp;quot;Line: &amp;quot;&amp;lt;&amp;lt;line&amp;lt;&amp;lt;std::endl;&lt;br /&gt;
			//if (!(line == &amp;quot;D2SG&amp;quot;)) {&lt;br /&gt;
			if (line.compare(&amp;quot;D2SG&amp;quot;) != 0){&lt;br /&gt;
				std::cout&amp;lt;&amp;lt;&amp;quot;wrong grid-file format &amp;quot;&amp;lt;&amp;lt;line.compare(&amp;quot;D2SG&amp;quot;)&amp;lt;&amp;lt;std::endl;&lt;br /&gt;
				error = true;&lt;br /&gt;
			}&lt;br /&gt;
			else {&lt;br /&gt;
				std::cout&amp;lt;&amp;lt;&amp;quot;Valid grid-file found!&amp;quot;&amp;lt;&amp;lt;std::endl;&lt;br /&gt;
			}&lt;br /&gt;
		}&lt;br /&gt;
		if (std::getline(inFile, line)) {&lt;br /&gt;
			_gridSize = stringToInt(line);&lt;br /&gt;
			//std::cout&amp;lt;&amp;lt;&amp;quot;gridsize: &amp;quot;&amp;lt;&amp;lt;_gridSize&amp;lt;&amp;lt;std::endl;&lt;br /&gt;
		}&lt;br /&gt;
		else {&lt;br /&gt;
			error = true;&lt;br /&gt;
		}&lt;br /&gt;
		if (std::getline(inFile, line)) {&lt;br /&gt;
			_size = stringToInt(line);&lt;br /&gt;
			//std::cout&amp;lt;&amp;lt;&amp;quot;quadsize: &amp;quot;&amp;lt;&amp;lt;_size&amp;lt;&amp;lt;std::endl;&lt;br /&gt;
		}&lt;br /&gt;
		else {&lt;br /&gt;
			error = true;&lt;br /&gt;
		}&lt;br /&gt;
		if (std::getline(inFile, line)) {&lt;br /&gt;
			numCoordinates = stringToInt(line);&lt;br /&gt;
			//std::cout&amp;lt;&amp;lt;&amp;quot;numCoords: &amp;quot;&amp;lt;&amp;lt;numCoordinates&amp;lt;&amp;lt;std::endl;&lt;br /&gt;
		}&lt;br /&gt;
		else {&lt;br /&gt;
			error = true;&lt;br /&gt;
		}&lt;br /&gt;
		if (!error) {&lt;br /&gt;
			_grid = new Vec3f*[_gridSize];&lt;br /&gt;
			for(int y=0; y&amp;lt;_gridSize; ++y) {&lt;br /&gt;
				_grid[y] = new Vec3f[_gridSize];&lt;br /&gt;
				for (int x=0; x&amp;lt;_gridSize; ++x) {&lt;br /&gt;
					Vec3f v;&lt;br /&gt;
					if (std::getline(inFile, line)) {&lt;br /&gt;
						v.x = stringToFloat(line);&lt;br /&gt;
					}&lt;br /&gt;
					if (std::getline(inFile, line)) {&lt;br /&gt;
						v.y = stringToFloat(line);&lt;br /&gt;
					}&lt;br /&gt;
					if (std::getline(inFile, line)) {&lt;br /&gt;
						v.z = stringToFloat(line);&lt;br /&gt;
					}&lt;br /&gt;
					_grid[y][x] = v;&lt;br /&gt;
				}&lt;br /&gt;
			}&lt;br /&gt;
		}&lt;br /&gt;
	}&lt;br /&gt;
	inFile.close();&lt;br /&gt;
	if (error) {&lt;br /&gt;
		_gridSize = GRIDSIZE;&lt;br /&gt;
		_size = 12;&lt;br /&gt;
		_grid = 0;&lt;br /&gt;
	}&lt;br /&gt;
	_numVertices = (_gridSize*_gridSize);&lt;br /&gt;
	_numTriangles = ((_gridSize - 1) * (_gridSize - 1)) * 2;&lt;br /&gt;
	_numTriangleIndices = _numTriangles * 3;&lt;br /&gt;
	_origin = Vec3f(-_size/2*_gridSize, 0, _size/2*_gridSize);&lt;br /&gt;
	return true;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
=Usage example=&lt;br /&gt;
&lt;br /&gt;
Finally this is all you have to do to generate the grid and display it in your scene.&lt;br /&gt;
{{CppSourceCode|&lt;br /&gt;
description= app.cpp| &lt;br /&gt;
code=&lt;br /&gt;
&amp;lt;source lang=&amp;quot;cpp&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
	// initialize a new grid (args: quadsize, model-name, filename (if applicable)&lt;br /&gt;
	_grid = new DynamicGrid(12.0f, &amp;quot;grid&amp;quot;, &amp;quot;grid-filename&amp;quot;);&lt;br /&gt;
	// do not forget to load a material and apply it to the mesh&lt;br /&gt;
	_grid-&amp;gt;setMaterial(gridMatRes);&lt;br /&gt;
	// generate the grid&lt;br /&gt;
	_grid-&amp;gt;generate();&lt;br /&gt;
	// add the grid-model to the RootNode&lt;br /&gt;
	_grid-&amp;gt;addCustomModelNode(RootNode);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
'''TODO'''&lt;/div&gt;</summary>
		<author><name>Wakko</name></author>	</entry>

	<entry>
		<id>http://horde3d.org/wiki/index.php?title=Procedurally_generated_geometry_tutorial&amp;diff=568</id>
		<title>Procedurally generated geometry tutorial</title>
		<link rel="alternate" type="text/html" href="http://horde3d.org/wiki/index.php?title=Procedurally_generated_geometry_tutorial&amp;diff=568"/>
				<updated>2009-10-26T12:00:02Z</updated>
		
		<summary type="html">&lt;p&gt;Wakko: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;'''Work in progress   - Due to the current changes in the Horde API this tutorial will be delayed '''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
= Important notes=&lt;br /&gt;
* The code used here has been tested with Horde3D 1.0.0 beta2 and beta3 and will '''NOT''' work with the latest release (beta4)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=Overview=&lt;br /&gt;
==Basic approach==&lt;br /&gt;
To create and display a procedurally generated mesh that, instead of being loaded from a Horde3D Scene node and a geoemtry file(*.scene.xml, *.geo), will be created in-memory by some algorithm, you have to create a mesh first and then &amp;quot;fake&amp;quot; the .geo-file and the scene node itself and pass it to the engine.&lt;br /&gt;
&lt;br /&gt;
To do that you have to create your procedural geometry first. This is easy for simple shapes like single triangles, squares or triangle-strips, but will become way more difficult when we try to generate complex meshes, e.g. when we have a cloud of points in 3D space and have to describe which points make triangles, and which don't (calculating the triangle indices, texture coordinates and normals).&lt;br /&gt;
&lt;br /&gt;
When we have calculated the geometry itself we need to create a char-stream to make Horde believe the geometry has been read from a file and pass it to Horde as a geometry Resource.&lt;br /&gt;
The final step is to create a Horde3D Scene Node from our procedurally generated mesh and render it into our scene.&lt;br /&gt;
[http://musicracer.de/images/Screenshot-1_small.jpg &lt;br /&gt;
This is how it could look like]&lt;br /&gt;
&lt;br /&gt;
=StreamGenerator=&lt;br /&gt;
&lt;br /&gt;
These classes are only for creating the character stream that will contain the geometry resource.&lt;br /&gt;
&lt;br /&gt;
{{CppSourceCode|&lt;br /&gt;
description= StreamGenerator.h| &lt;br /&gt;
code=&lt;br /&gt;
&amp;lt;source lang=&amp;quot;cpp&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
#pragma once&lt;br /&gt;
#include &amp;lt;sstream&amp;gt;&lt;br /&gt;
#include &amp;lt;string&amp;gt;&lt;br /&gt;
#include &amp;lt;iostream&amp;gt;&lt;br /&gt;
&lt;br /&gt;
class StreamGenerator &lt;br /&gt;
{&lt;br /&gt;
public:&lt;br /&gt;
	StreamGenerator();&lt;br /&gt;
	virtual ~StreamGenerator();&lt;br /&gt;
	virtual const char* getStream() = 0;&lt;br /&gt;
	virtual const int getStreamSize() = 0;&lt;br /&gt;
};&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{CppSourceCode|&lt;br /&gt;
description= StreamGenerator.cpp| &lt;br /&gt;
code=&lt;br /&gt;
&amp;lt;source lang=&amp;quot;cpp&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;quot;StreamGenerator.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
StreamGenerator::StreamGenerator() &lt;br /&gt;
{&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
StreamGenerator::~StreamGenerator()&lt;br /&gt;
{&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{CppSourceCode|&lt;br /&gt;
description= GeometryStreamGenerator.h| &lt;br /&gt;
code=&lt;br /&gt;
&amp;lt;source lang=&amp;quot;cpp&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
#pragma once&lt;br /&gt;
#include &amp;quot;StreamGenerator.h&amp;quot;&lt;br /&gt;
#include &amp;quot;CustomGeometry.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
class GeometryStreamGenerator : public StreamGenerator&lt;br /&gt;
{&lt;br /&gt;
private:&lt;br /&gt;
	std::stringstream* ss;&lt;br /&gt;
	void generate();&lt;br /&gt;
	int numVertices, numTriangleIndices;&lt;br /&gt;
	char* _stream;&lt;br /&gt;
	CustomGeometry* _geom;&lt;br /&gt;
&lt;br /&gt;
public:&lt;br /&gt;
	GeometryStreamGenerator(CustomGeometry* geom_);&lt;br /&gt;
	~GeometryStreamGenerator();&lt;br /&gt;
	const char* getStream();&lt;br /&gt;
	const std::stringstream* getStringStream() { return ss; };&lt;br /&gt;
	const int getStreamSize();&lt;br /&gt;
	const int getNumVertices();&lt;br /&gt;
	const int getNumTriangleIndices();&lt;br /&gt;
	void release();&lt;br /&gt;
};&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{CppSourceCode|&lt;br /&gt;
description= GeometryStreamGenerator.cpp| &lt;br /&gt;
code=&lt;br /&gt;
&amp;lt;source lang=&amp;quot;cpp&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;quot;GeometryStreamGenerator.h&amp;quot;&lt;br /&gt;
#include &amp;quot;time.h&amp;quot;&lt;br /&gt;
#include &amp;quot;utMath.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
GeometryStreamGenerator::GeometryStreamGenerator(CustomGeometry* geom_) : _geom(geom_)&lt;br /&gt;
{&lt;br /&gt;
	ss = new std::stringstream();&lt;br /&gt;
	generate();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
GeometryStreamGenerator::~GeometryStreamGenerator()&lt;br /&gt;
{&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void GeometryStreamGenerator::generate()&lt;br /&gt;
{&lt;br /&gt;
	numVertices = _geom-&amp;gt;getNumVertices();&lt;br /&gt;
	numTriangleIndices = _geom-&amp;gt;getNumTriangleIndices();&lt;br /&gt;
	const std::string _magicHeader = &amp;quot;H3DG&amp;quot;;&lt;br /&gt;
	const int _version = 5;&lt;br /&gt;
	const int _numJoints = 1;&lt;br /&gt;
	const float _identityMatrix[] = {	1.0f, 0.0f, 0.0f, 0.0f,  &lt;br /&gt;
						0.0f, 1.0f, 0.0f, 0.0f,  &lt;br /&gt;
						0.0f, 0.0f, 1.0f, 0.0f,  &lt;br /&gt;
						0.0f, 0.0f, 0.0f, 1.0f};&lt;br /&gt;
	const int _numVertexStreams = 3;&lt;br /&gt;
	const int _magicVertices = 0;&lt;br /&gt;
	const int _vertexStreamElementSize = 12;&lt;br /&gt;
	const float* _positions = _geom-&amp;gt;getPositions();&lt;br /&gt;
	const int _magicNormals = 1;&lt;br /&gt;
	const int _normalsStreamElementSize = 6;&lt;br /&gt;
	const float* _normals = _geom-&amp;gt;getNormals();&lt;br /&gt;
	const int _magicTextureCoords1 = 6;&lt;br /&gt;
	const int _texCoordStreamElementSize = 8;&lt;br /&gt;
	const float* _texCoords = _geom-&amp;gt;getTexCoords();&lt;br /&gt;
	const int* _triangleIndices = _geom-&amp;gt;getTriangleIndices();&lt;br /&gt;
	const int _numMorphTragets = 0;&lt;br /&gt;
	// header&lt;br /&gt;
	ss-&amp;gt;write(_magicHeader.c_str(), 4*sizeof(char));&lt;br /&gt;
	ss-&amp;gt;write((char*)&amp;amp;_version, sizeof(int));&lt;br /&gt;
	// joints (mandatory)&lt;br /&gt;
	ss-&amp;gt;write((char*)&amp;amp;_numJoints, sizeof(int));&lt;br /&gt;
	for (int i=0; i&amp;lt;16; ++i) {&lt;br /&gt;
		ss-&amp;gt;write((char*)&amp;amp;_identityMatrix[i], sizeof(float));&lt;br /&gt;
	}&lt;br /&gt;
	// vertices&lt;br /&gt;
	ss-&amp;gt;write((char*)&amp;amp;_numVertexStreams, sizeof(int));&lt;br /&gt;
	const int numVerts = _geom-&amp;gt;getNumVertices();&lt;br /&gt;
	ss-&amp;gt;write((char*)&amp;amp;numVerts, sizeof(int));&lt;br /&gt;
	ss-&amp;gt;write((char*)&amp;amp;_magicVertices, sizeof(int));&lt;br /&gt;
	ss-&amp;gt;write((char*)&amp;amp;_vertexStreamElementSize, sizeof(int));&lt;br /&gt;
	for (int i=0; i&amp;lt;_geom-&amp;gt;getNumVertices()*3; ++i) {&lt;br /&gt;
		ss-&amp;gt;write((char*)&amp;amp;_positions[i], sizeof(float));&lt;br /&gt;
	}&lt;br /&gt;
	// normals&lt;br /&gt;
	ss-&amp;gt;write((char*)&amp;amp;_magicNormals, sizeof(int));&lt;br /&gt;
	ss-&amp;gt;write((char*)&amp;amp;_normalsStreamElementSize, sizeof(int));&lt;br /&gt;
	for (int i=0; i&amp;lt;_geom-&amp;gt;getNumVertices()*3; ++i) {&lt;br /&gt;
		// do not forget to mutliply the value with 32767 and &lt;br /&gt;
		// then convert it to short before writing to the stream&lt;br /&gt;
		const short f = (short)(_normals[i]*32767);&lt;br /&gt;
		ss-&amp;gt;write((char*)&amp;amp;f, sizeof(short));&lt;br /&gt;
	}&lt;br /&gt;
	// texture coordinates&lt;br /&gt;
	ss-&amp;gt;write((char*)&amp;amp;_magicTextureCoords1, sizeof(int));&lt;br /&gt;
	ss-&amp;gt;write((char*)&amp;amp;_texCoordStreamElementSize, sizeof(int));&lt;br /&gt;
	for (int i=0; i&amp;lt;_geom-&amp;gt;getNumVertices()*2; ++i) {&lt;br /&gt;
		ss-&amp;gt;write((char*)&amp;amp;_texCoords[i], sizeof(float));&lt;br /&gt;
	}&lt;br /&gt;
	// triangle indices&lt;br /&gt;
	const int numTriangleIndices = _geom-&amp;gt;getNumTriangleIndices();&lt;br /&gt;
	ss-&amp;gt;write((char*)&amp;amp;numTriangleIndices, sizeof(int));&lt;br /&gt;
	for (int i=0; i&amp;lt;_geom-&amp;gt;getNumTriangleIndices(); ++i) {&lt;br /&gt;
		ss-&amp;gt;write((char*)&amp;amp;_triangleIndices[i], sizeof(int));&lt;br /&gt;
	}&lt;br /&gt;
	ss-&amp;gt;write((char*)&amp;amp;_numMorphTragets, sizeof(int));&lt;br /&gt;
	_stream = new char[ss-&amp;gt;tellp()];&lt;br /&gt;
	ss-&amp;gt;read(_stream, ss-&amp;gt;tellp());&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
const char* GeometryStreamGenerator::getStream()&lt;br /&gt;
{&lt;br /&gt;
	return _stream;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
const int GeometryStreamGenerator::getStreamSize() &lt;br /&gt;
{&lt;br /&gt;
	int t = (int)ss-&amp;gt;tellp();&lt;br /&gt;
	return t;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
const int GeometryStreamGenerator::getNumVertices()&lt;br /&gt;
{&lt;br /&gt;
	return numVertices;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
const int GeometryStreamGenerator::getNumTriangleIndices()&lt;br /&gt;
{&lt;br /&gt;
	return numTriangleIndices;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void GeometryStreamGenerator::release()&lt;br /&gt;
{&lt;br /&gt;
	ss-&amp;gt;flush();&lt;br /&gt;
	ss-&amp;gt;clear();&lt;br /&gt;
	delete ss;&lt;br /&gt;
	ss = 0;&lt;br /&gt;
	delete[] _stream;&lt;br /&gt;
	_stream = 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
=CustomGeometry base class=&lt;br /&gt;
&lt;br /&gt;
Base class for the custom geometry. This class currently contains lots of deprecated stuff, e.g. the update() function. This function was used to update an in-memory gemoetry resource in the &amp;quot;punk-rock&amp;quot;-way. Until Horde3D Beta3 the geometry resources were read-only, so directmanipulation of vertices was impossible. To modify the vertices I had to unload the geometry resource, re-create it with the new vertex-positions and load it into Horde again. '''This is not necessary any more because since Beta4 the geometry resources are not read-only anymore.'''&lt;br /&gt;
&lt;br /&gt;
All custom geometry classes should be derived from this class and implement the abstract functions as needed. (See the examples below)&lt;br /&gt;
&lt;br /&gt;
{{CppSourceCode|&lt;br /&gt;
description= CustomGeometry.h| &lt;br /&gt;
code=&lt;br /&gt;
&amp;lt;source lang=&amp;quot;cpp&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
#pragma once&lt;br /&gt;
/**&lt;br /&gt;
 * Abstract class for custom/dynamic geometry&lt;br /&gt;
 **/&lt;br /&gt;
#include &amp;quot;utMath.h&amp;quot;&lt;br /&gt;
#include &amp;quot;Horde3D.h&amp;quot;&lt;br /&gt;
#include &amp;lt;string&amp;gt;&lt;br /&gt;
&lt;br /&gt;
class CustomGeometry &lt;br /&gt;
{&lt;br /&gt;
protected:&lt;br /&gt;
	float _size;&lt;br /&gt;
	Vec3f _origin;&lt;br /&gt;
	int _numVertices;&lt;br /&gt;
	int _numTriangles;&lt;br /&gt;
	int _numTriangleIndices;&lt;br /&gt;
	float* _positions;&lt;br /&gt;
	float* _normals;&lt;br /&gt;
	float* _texCoords;&lt;br /&gt;
	int* _tIndices;&lt;br /&gt;
	std::string _name;&lt;br /&gt;
	NodeHandle _model;&lt;br /&gt;
	NodeHandle _parent;&lt;br /&gt;
	ResHandle _material;&lt;br /&gt;
	virtual void generatePositions() = 0;&lt;br /&gt;
	virtual void generateNormals() = 0;&lt;br /&gt;
	virtual void generateTexCoords() = 0;&lt;br /&gt;
	virtual void generateTriangleIndices() = 0;&lt;br /&gt;
&lt;br /&gt;
public:&lt;br /&gt;
	CustomGeometry();&lt;br /&gt;
	virtual void generate() = 0;&lt;br /&gt;
	const int getNumVertices() { return _numVertices; }&lt;br /&gt;
	const float* getPositions() { return _positions; }&lt;br /&gt;
	const float* getNormals() { return _normals; }&lt;br /&gt;
	const float* getTexCoords() { return _texCoords; }&lt;br /&gt;
	const int* getTriangleIndices() { return _tIndices; }&lt;br /&gt;
	const int getNumTriangles() { return _numTriangles; }&lt;br /&gt;
	const int getNumTriangleIndices() { return _numTriangleIndices; }&lt;br /&gt;
	void release();&lt;br /&gt;
	const Vec3f getInterpolatedNormal(Vec3f n1_, Vec3f n2_);&lt;br /&gt;
	// pass -1 as the parameter to leave the parent node unchanged&lt;br /&gt;
	void addCustomModelNode(NodeHandle parent_);&lt;br /&gt;
	bool removeCustomModelNode();&lt;br /&gt;
	void setMaterial(ResHandle material_) { _material = material_; }&lt;br /&gt;
	void setParent(NodeHandle parent_) { _parent = parent_; }&lt;br /&gt;
	NodeHandle getModel() { return _model; }&lt;br /&gt;
	ResHandle getMaterial() { return _material; }&lt;br /&gt;
	void update();&lt;br /&gt;
	Vec3f getOrigin() { return _origin; }&lt;br /&gt;
	void setOrigin(Vec3f origin_) { _origin = origin_; }&lt;br /&gt;
	const float getSize() { return _size; }&lt;br /&gt;
};&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{CppSourceCode|&lt;br /&gt;
description= CustomGeometry.cpp| &lt;br /&gt;
code=&lt;br /&gt;
&amp;lt;source lang=&amp;quot;cpp&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;quot;CustomGeometry.h&amp;quot;&lt;br /&gt;
#include &amp;lt;iostream&amp;gt;&lt;br /&gt;
#include &amp;lt;string&amp;gt;&lt;br /&gt;
#include &amp;lt;sstream&amp;gt;&lt;br /&gt;
#include &amp;lt;fstream&amp;gt;&lt;br /&gt;
#include &amp;quot;GeometryStreamGenerator.h&amp;quot;&lt;br /&gt;
#include &amp;quot;Horde3DUtils.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
CustomGeometry::CustomGeometry() : _name(&amp;quot;default&amp;quot;), _size(1)&lt;br /&gt;
{&lt;br /&gt;
	_origin = Vec3f(0, 0, 0);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void CustomGeometry::release()&lt;br /&gt;
{&lt;br /&gt;
	delete[] _positions;&lt;br /&gt;
	_positions = 0;&lt;br /&gt;
	delete[] _normals;&lt;br /&gt;
	_normals = 0;&lt;br /&gt;
	delete[] _texCoords;&lt;br /&gt;
	_texCoords = 0;&lt;br /&gt;
	delete[] _tIndices;&lt;br /&gt;
	_tIndices = 0;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
const Vec3f CustomGeometry::getInterpolatedNormal(Vec3f n1_, Vec3f n2_) &lt;br /&gt;
{&lt;br /&gt;
	Vec3f newNormal = n1_ + n2_;&lt;br /&gt;
	float length = newNormal.length();&lt;br /&gt;
	return newNormal/length;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void CustomGeometry::addCustomModelNode(NodeHandle parent_)&lt;br /&gt;
{&lt;br /&gt;
	//std::stringstream* sa = new std::stringstream();&lt;br /&gt;
	std::stringstream ss;&lt;br /&gt;
	if (parent_ != -1) &lt;br /&gt;
		_parent = parent_;&lt;br /&gt;
	ss&amp;lt;&amp;lt; &amp;quot;customGeometry-&amp;quot;;&lt;br /&gt;
	ss&amp;lt;&amp;lt;_name;&lt;br /&gt;
	GeometryStreamGenerator* gsg = new GeometryStreamGenerator(this);&lt;br /&gt;
	ResHandle customGeoRes = Horde3D::addResource(ResourceTypes::Geometry, ss.str().c_str(), 0);&lt;br /&gt;
	Horde3D::loadResource(customGeoRes, gsg-&amp;gt;getStream(), gsg-&amp;gt;getStreamSize());&lt;br /&gt;
	// model_node_name&lt;br /&gt;
	ss&amp;lt;&amp;lt;&amp;quot;-Node&amp;quot;;&lt;br /&gt;
	_model = Horde3D::addModelNode(_parent, ss.str().c_str(), customGeoRes);&lt;br /&gt;
	// mesh_name&lt;br /&gt;
	ss&amp;lt;&amp;lt;&amp;quot;-Mesh&amp;quot;;&lt;br /&gt;
	Horde3D::addMeshNode(_model, ss.str().c_str(), _material, 0, gsg-&amp;gt;getNumTriangleIndices(), 0, gsg-&amp;gt;getNumVertices()-1);&lt;br /&gt;
	Horde3DUtils::dumpMessages();&lt;br /&gt;
	ss.str(&amp;quot;&amp;quot;);&lt;br /&gt;
	ss.clear();&lt;br /&gt;
	ss.flush();&lt;br /&gt;
	gsg-&amp;gt;release();&lt;br /&gt;
	delete gsg;&lt;br /&gt;
	gsg = 0;&lt;br /&gt;
	//Horde3D::setNodeTransform(_model, _origin.x, _origin.y, _origin.z, 0, 0, 0, 1, 1, 1);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
bool CustomGeometry::removeCustomModelNode()&lt;br /&gt;
{&lt;br /&gt;
	std::stringstream* ss = new std::stringstream();&lt;br /&gt;
	*ss&amp;lt;&amp;lt; &amp;quot;customGeometry-&amp;quot;;&lt;br /&gt;
	*ss&amp;lt;&amp;lt;_name;&lt;br /&gt;
	ResHandle rh = Horde3D::findResource(ResourceTypes::Geometry, ss-&amp;gt;str().c_str());&lt;br /&gt;
	if (Horde3D::isResourceLoaded(rh)) {&lt;br /&gt;
		Horde3D::removeResource(rh);&lt;br /&gt;
		Horde3D::unloadResource(rh);&lt;br /&gt;
		Horde3D::removeNode(_model);&lt;br /&gt;
		Horde3D::releaseUnusedResources();&lt;br /&gt;
		Horde3DUtils::dumpMessages();&lt;br /&gt;
		delete ss;&lt;br /&gt;
		return true;&lt;br /&gt;
	}&lt;br /&gt;
	else &lt;br /&gt;
		return false;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void CustomGeometry::update()&lt;br /&gt;
{&lt;br /&gt;
	removeCustomModelNode();&lt;br /&gt;
	addCustomModelNode(-1);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
=Simple Square=&lt;br /&gt;
&lt;br /&gt;
A simple two-sided (hard-coded) square. This is pretty straight forward and demonstrates how to derive from the CustomGeometry class and how the triangle indices work.&lt;br /&gt;
&lt;br /&gt;
{{CppSourceCode|&lt;br /&gt;
description= DynamicSquare.h| &lt;br /&gt;
code=&lt;br /&gt;
&amp;lt;source lang=&amp;quot;cpp&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
/**&lt;br /&gt;
 * Class representing a square &lt;br /&gt;
 **/&lt;br /&gt;
#pragma once&lt;br /&gt;
#include &amp;quot;CustomGeometry.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
class DynamicSquare : public CustomGeometry&lt;br /&gt;
{&lt;br /&gt;
protected:&lt;br /&gt;
	virtual void generatePositions();&lt;br /&gt;
	virtual void generateNormals();&lt;br /&gt;
	virtual void generateTexCoords();&lt;br /&gt;
	virtual void generateTriangleIndices();&lt;br /&gt;
&lt;br /&gt;
public:&lt;br /&gt;
	DynamicSquare();&lt;br /&gt;
	virtual void generate();&lt;br /&gt;
	DynamicSquare(const float size_, const std::string name_);&lt;br /&gt;
};&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{CppSourceCode|&lt;br /&gt;
description= DynamicSquare.cpp| &lt;br /&gt;
code=&lt;br /&gt;
&amp;lt;source lang=&amp;quot;cpp&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;quot;DynamicSquare.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
DynamicSquare::DynamicSquare() : CustomGeometry()&lt;br /&gt;
{&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
DynamicSquare::DynamicSquare(const float size_, const std::string name_) &lt;br /&gt;
{&lt;br /&gt;
	_size = size_;&lt;br /&gt;
	_name = name_;&lt;br /&gt;
	_numVertices = 8;&lt;br /&gt;
	_numTriangles = 4;&lt;br /&gt;
	_numTriangleIndices = (_numVertices - 2) * 3;&lt;br /&gt;
	//generate();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void DynamicSquare::generate() &lt;br /&gt;
{&lt;br /&gt;
	generatePositions();&lt;br /&gt;
	generateNormals();&lt;br /&gt;
	generateTexCoords();&lt;br /&gt;
	generateTriangleIndices();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void DynamicSquare::generatePositions() &lt;br /&gt;
{&lt;br /&gt;
	_positions = new float[_numVertices * 3 * 2];&lt;br /&gt;
	// front left point (x/y/z)&lt;br /&gt;
	_positions[0] = _origin.x * _size - _size/2;&lt;br /&gt;
	_positions[1] = _origin.y;&lt;br /&gt;
	_positions[2] = _origin.z * _size -_size/2;&lt;br /&gt;
	// front right point (x/y/z)&lt;br /&gt;
	_positions[3] = _origin.x * _size + _size/2;&lt;br /&gt;
	_positions[4] = _origin.y;&lt;br /&gt;
	_positions[5] = _origin.z * _size - _size/2;&lt;br /&gt;
	// back left point (x/y/z)&lt;br /&gt;
	_positions[6] = _origin.x * _size - _size/2;&lt;br /&gt;
	_positions[7] = _origin.y;&lt;br /&gt;
	_positions[8] = _origin.z * _size + _size/2;&lt;br /&gt;
	// back right point (x/y/z)&lt;br /&gt;
	_positions[9] = _origin.x * _size + _size/2;&lt;br /&gt;
	_positions[10] = _origin.y;&lt;br /&gt;
	_positions[11] = _origin.z * _size + _size/2;&lt;br /&gt;
&lt;br /&gt;
        // comment the bottom side if you do not want to have a two-sided sq&lt;br /&gt;
	// bottom sideuare&lt;br /&gt;
	// front left point (x/y/z)&lt;br /&gt;
	_positions[12] = _origin.x * _size - _size/2;&lt;br /&gt;
	_positions[13] = _origin.y-0.5;&lt;br /&gt;
	_positions[14] = _origin.z * _size - _size/2;&lt;br /&gt;
	// front right point (x/y/z)&lt;br /&gt;
	_positions[15] = _origin.x * _size + _size/2;&lt;br /&gt;
	_positions[16] = _origin.y-0.5;&lt;br /&gt;
	_positions[17] = _origin.z * _size - _size/2;&lt;br /&gt;
	// back left point (x/y/z)&lt;br /&gt;
	_positions[18] = _origin.x * _size - _size/2;&lt;br /&gt;
	_positions[19] = _origin.y-0.5;&lt;br /&gt;
	_positions[20] = _origin.z * _size + _size/2;&lt;br /&gt;
	// back right point (x/y/z)&lt;br /&gt;
	_positions[21] = _origin.x * _size + _size/2;&lt;br /&gt;
	_positions[22] = _origin.y-0.5;&lt;br /&gt;
	_positions[23] = _origin.z * _size + _size/2;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void DynamicSquare::generateNormals() &lt;br /&gt;
{&lt;br /&gt;
	_normals = new float[_numVertices * 3*2];&lt;br /&gt;
	for (int i=0; i&amp;lt; 12; i+=3) {&lt;br /&gt;
		_normals[i] = 0;&lt;br /&gt;
		_normals[i+1] = 1;&lt;br /&gt;
		_normals[i+2] = 0;&lt;br /&gt;
	}&lt;br /&gt;
	for (int i=13; i&amp;lt; 24; i+=3) {&lt;br /&gt;
		_normals[i] = 0;&lt;br /&gt;
		_normals[i+1] = -1;&lt;br /&gt;
		_normals[i+2] = 0;&lt;br /&gt;
	}&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void DynamicSquare::generateTexCoords()&lt;br /&gt;
{&lt;br /&gt;
	_texCoords = new float[_numVertices * 2 * 2];&lt;br /&gt;
	_texCoords[0] = 0.0f; &lt;br /&gt;
	_texCoords[1] = 0.0f;&lt;br /&gt;
	_texCoords[2] = 1.0f; &lt;br /&gt;
	_texCoords[3] = 0.0f;&lt;br /&gt;
	_texCoords[4] = 0.0f; &lt;br /&gt;
	_texCoords[5] = 1.0f;&lt;br /&gt;
	_texCoords[6] = 1.0f; &lt;br /&gt;
	_texCoords[7] = 1.0f;&lt;br /&gt;
	_texCoords[8] = 0.0f; &lt;br /&gt;
	_texCoords[9] = 0.0f;&lt;br /&gt;
	_texCoords[10] = 1.0f; &lt;br /&gt;
	_texCoords[11] = 0.0f;&lt;br /&gt;
	_texCoords[12] = 0.0f; &lt;br /&gt;
	_texCoords[13] = 1.0f;&lt;br /&gt;
	_texCoords[14] = 1.0f; &lt;br /&gt;
	_texCoords[15] = 1.0f;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void DynamicSquare::generateTriangleIndices() &lt;br /&gt;
{&lt;br /&gt;
	_tIndices = new int[_numTriangleIndices ];&lt;br /&gt;
	_tIndices[0] = 0;&lt;br /&gt;
	_tIndices[1] = 2;&lt;br /&gt;
	_tIndices[2] = 1;&lt;br /&gt;
	_tIndices[3] = 1;&lt;br /&gt;
	_tIndices[4] = 2;&lt;br /&gt;
	_tIndices[5] = 3;&lt;br /&gt;
	_tIndices[6] = 5;&lt;br /&gt;
	_tIndices[7] = 7;&lt;br /&gt;
	_tIndices[8] = 6;&lt;br /&gt;
	_tIndices[9] = 6;&lt;br /&gt;
	_tIndices[10] = 4;&lt;br /&gt;
	_tIndices[11] = 5;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
=Simple Grid=&lt;br /&gt;
&lt;br /&gt;
All the work above was made to create my own interactive terrain generator(screenshot on top of this page) for a A* pathfinding demonstrator. The Grid-class actually generates a 2-dimensional array of Vec3f(s) and allows to extrude each point and re-generate the mesh in realtime. The internal representation is writeable and in case of a change of any point the overridden update() function will be called to update the Horde3D geometry resource.&lt;br /&gt;
&lt;br /&gt;
[http://musicracer.de/images/grid_01_english.png&lt;br /&gt;
This is how it looks internally]&lt;br /&gt;
{{CppSourceCode|&lt;br /&gt;
description= DynamicGrid.h| &lt;br /&gt;
code=&lt;br /&gt;
&amp;lt;source lang=&amp;quot;cpp&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
/**&lt;br /&gt;
 * Class representing a grid&lt;br /&gt;
 **/&lt;br /&gt;
#pragma once&lt;br /&gt;
#include &amp;quot;CustomGeometry.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
class DynamicGrid : public CustomGeometry&lt;br /&gt;
{&lt;br /&gt;
protected:&lt;br /&gt;
	virtual void generatePositions();&lt;br /&gt;
	virtual void generateNormals();&lt;br /&gt;
	virtual void generateTexCoords();&lt;br /&gt;
	virtual void generateTriangleIndices();&lt;br /&gt;
       // generate the internal representation of the grid (writeable to allow updates of single points!)&lt;br /&gt;
	void generateGrid();&lt;br /&gt;
	int _gridSize;&lt;br /&gt;
	Vec3f** _grid;&lt;br /&gt;
	std::string _fileName;&lt;br /&gt;
&lt;br /&gt;
public:&lt;br /&gt;
	DynamicGrid();&lt;br /&gt;
	virtual void generate();&lt;br /&gt;
	DynamicGrid(const float size_, const std::string name_, std::string fileName_);&lt;br /&gt;
	Vec3f getPointAt(int x_, int y_) { return _grid[y_][x_]; }&lt;br /&gt;
	// update a point of our grid (args: index x, index y, new position)&lt;br /&gt;
	void setPointAt(int x_, int y_, Vec3f newPos_) { _grid[y_][x_] = newPos_; }&lt;br /&gt;
	int getGridSize() { return _gridSize; }&lt;br /&gt;
	// overwrite update() from parent class&lt;br /&gt;
	void update();&lt;br /&gt;
	// read and write grids from/to files&lt;br /&gt;
	void saveGridToFile(std::string fileName_);&lt;br /&gt;
	bool readGridFromFile(std::string fileName_);&lt;br /&gt;
&lt;br /&gt;
};&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{CppSourceCode|&lt;br /&gt;
description= DynamicGrid.cpp| &lt;br /&gt;
code=&lt;br /&gt;
&amp;lt;source lang=&amp;quot;cpp&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;quot;DynamicGrid.h&amp;quot;&lt;br /&gt;
#include &amp;quot;rng.h&amp;quot;&lt;br /&gt;
#include &amp;lt;iostream&amp;gt;&lt;br /&gt;
#include &amp;lt;string&amp;gt;&lt;br /&gt;
#include &amp;lt;sstream&amp;gt;&lt;br /&gt;
#include &amp;lt;fstream&amp;gt;&lt;br /&gt;
#include &amp;quot;util.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
#define GRIDSIZE 50&lt;br /&gt;
&lt;br /&gt;
DynamicGrid::DynamicGrid() : CustomGeometry()&lt;br /&gt;
{&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
DynamicGrid::DynamicGrid(const float size_, const std::string name_, std::string fileName_) : _fileName(fileName_) &lt;br /&gt;
{&lt;br /&gt;
	_name = name_;&lt;br /&gt;
	_positions = 0;&lt;br /&gt;
	_normals = 0;&lt;br /&gt;
	_texCoords = 0;&lt;br /&gt;
	_tIndices = 0;&lt;br /&gt;
	readGridFromFile(_fileName);&lt;br /&gt;
	_numVertices = (_gridSize*_gridSize);&lt;br /&gt;
	_numTriangles = ((_gridSize - 1) * (_gridSize - 1)) * 2;&lt;br /&gt;
	_numTriangleIndices = _numTriangles * 3;&lt;br /&gt;
	_origin = Vec3f(-_size/2*_gridSize, 0, _size/2*_gridSize);&lt;br /&gt;
	/*&lt;br /&gt;
	std::cout&amp;lt;&amp;lt;&amp;quot;numVerts: &amp;quot;&amp;lt;&amp;lt;_numVertices&amp;lt;&amp;lt;std::endl;&lt;br /&gt;
	std::cout&amp;lt;&amp;lt;&amp;quot;numTris: &amp;quot;&amp;lt;&amp;lt;_numTriangles&amp;lt;&amp;lt;std::endl;&lt;br /&gt;
	std::cout&amp;lt;&amp;lt;&amp;quot;numTInds: &amp;quot;&amp;lt;&amp;lt;_numTriangleIndices&amp;lt;&amp;lt;std::endl;&lt;br /&gt;
	std::cout&amp;lt;&amp;lt;&amp;quot;size: &amp;quot;&amp;lt;&amp;lt;_size&amp;lt;&amp;lt;std::endl;&lt;br /&gt;
	*/&lt;br /&gt;
	//std::cout&amp;lt;&amp;lt;_origin.x&amp;lt;&amp;lt;&amp;quot;/&amp;quot;&amp;lt;&amp;lt;_origin.y&amp;lt;&amp;lt;&amp;quot;/&amp;quot;&amp;lt;&amp;lt;_origin.z&amp;lt;&amp;lt;std::endl;&lt;br /&gt;
	//generate();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void DynamicGrid::generate() &lt;br /&gt;
{&lt;br /&gt;
	if (!_grid)&lt;br /&gt;
		generateGrid();&lt;br /&gt;
	generatePositions();&lt;br /&gt;
	generateNormals();&lt;br /&gt;
	generateTexCoords();&lt;br /&gt;
	generateTriangleIndices();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// the following two functions could be combined into one single loop, but I left it this way for clarity...&lt;br /&gt;
/**&lt;br /&gt;
 * This function simply generates a 2-dimensional array of Vec3f(s) with slightly random height values&lt;br /&gt;
 **/&lt;br /&gt;
void DynamicGrid::generateGrid()&lt;br /&gt;
{&lt;br /&gt;
	RNG rng;&lt;br /&gt;
	_grid = new Vec3f*[_gridSize];&lt;br /&gt;
	for (int y=0; y&amp;lt;_gridSize; ++y) {&lt;br /&gt;
		_grid[y] = new Vec3f[_gridSize];&lt;br /&gt;
		for (int x=0; x&amp;lt;_gridSize; ++x) {&lt;br /&gt;
			long rand = (abs((int)rng.rand_int31()) %3);&lt;br /&gt;
			_grid[y][x] = Vec3f(_origin.x/2+_size/2*x, rand, _origin.z/2-_size/2*y);&lt;br /&gt;
			//std::cout&amp;lt;&amp;lt;_grid[y][x].x&amp;lt;&amp;lt;&amp;quot;/&amp;quot;&amp;lt;&amp;lt;_grid[y][x].y&amp;lt;&amp;lt;&amp;quot;/&amp;quot;&amp;lt;&amp;lt;_grid[y][x].z&amp;lt;&amp;lt;std::endl;&lt;br /&gt;
		}&lt;br /&gt;
	}&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/**&lt;br /&gt;
 * Convert the grid's positions into a Horde3D vertex array.&lt;br /&gt;
 **/&lt;br /&gt;
void DynamicGrid::generatePositions() &lt;br /&gt;
{&lt;br /&gt;
	_positions = new float[_numVertices*3];&lt;br /&gt;
	int counter = 0;&lt;br /&gt;
	for (int i=0; i&amp;lt;_numVertices*3; i+=3) {&lt;br /&gt;
		int y = counter / _gridSize;&lt;br /&gt;
		int x = counter % _gridSize;&lt;br /&gt;
		_positions[i] = _grid[y][x].x;&lt;br /&gt;
		_positions[i+1] = _grid[y][x].y;&lt;br /&gt;
		_positions[i+2] = _grid[y][x].z;&lt;br /&gt;
		++counter;&lt;br /&gt;
	}&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void DynamicGrid::generateNormals() &lt;br /&gt;
{&lt;br /&gt;
	_normals = new float[_numVertices * 3];&lt;br /&gt;
	for (int i=0; i&amp;lt; _numVertices*3; i+=3) {&lt;br /&gt;
		int pos = i/3;&lt;br /&gt;
		int xPos = pos % _gridSize;&lt;br /&gt;
		int yPos = pos / _gridSize;&lt;br /&gt;
		Vec3f xPred;&lt;br /&gt;
		Vec3f xSucc;&lt;br /&gt;
		Vec3f yPred;&lt;br /&gt;
		Vec3f ySucc;&lt;br /&gt;
		Vec3f normal;&lt;br /&gt;
		if (xPos &amp;gt; 0 &amp;amp;&amp;amp; yPos &amp;gt; 0) {&lt;br /&gt;
			// if the current vertex is inside the grid we will calculate&lt;br /&gt;
			// two normals from the previous&amp;amp;next point and our current vertex&lt;br /&gt;
			if (xPos &amp;lt; _gridSize-1 &amp;amp;&amp;amp; yPos &amp;lt; _gridSize-1) {&lt;br /&gt;
				xSucc = _grid[yPos][xPos+1];&lt;br /&gt;
				xPred = _grid[yPos][xPos-1];&lt;br /&gt;
				ySucc = _grid[yPos+1][xPos];&lt;br /&gt;
				yPred = _grid[yPos-1][xPos];&lt;br /&gt;
				Vec3f v1 = xSucc - _grid[yPos][xPos];&lt;br /&gt;
				if (v1.y &amp;lt; 0)&lt;br /&gt;
					v1.y *= -1;&lt;br /&gt;
				Vec3f v2 = xPred - _grid[yPos][xPos];&lt;br /&gt;
				if (v2.y &amp;lt; 0)&lt;br /&gt;
					v2.y *= -1;&lt;br /&gt;
				v1 += v2;&lt;br /&gt;
				Vec3f v3 = ySucc - _grid[yPos][xPos];&lt;br /&gt;
				if (v3.y &amp;lt; 0)&lt;br /&gt;
					v3.y *= -1;&lt;br /&gt;
				Vec3f v4 = yPred - _grid[yPos][xPos];&lt;br /&gt;
				if (v4.y &amp;lt; 0)&lt;br /&gt;
					v4.y *= -1;&lt;br /&gt;
				v3 += v4;&lt;br /&gt;
				normal = getInterpolatedNormal(v1, v3);&lt;br /&gt;
			}&lt;br /&gt;
			// if the vertex is on the grid's border the normal will simply be 0/1/0&lt;br /&gt;
			else {&lt;br /&gt;
				normal = Vec3f(0,1,0);&lt;br /&gt;
			}&lt;br /&gt;
		}&lt;br /&gt;
		else {&lt;br /&gt;
			normal = Vec3f(0,1,0);&lt;br /&gt;
		}&lt;br /&gt;
		_normals[i] = normal.x;&lt;br /&gt;
		_normals[i+1] = normal.y;&lt;br /&gt;
		_normals[i+2] = normal.z;&lt;br /&gt;
	}&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void DynamicGrid::generateTexCoords()&lt;br /&gt;
{&lt;br /&gt;
	_texCoords = new float[_numVertices * 2];&lt;br /&gt;
	int counter = 0;&lt;br /&gt;
	int line = 0;&lt;br /&gt;
	for (int i=0; i&amp;lt;_numVertices*2; i+=2) {&lt;br /&gt;
		if ( line % 2 == 0) {&lt;br /&gt;
			if (counter %2 == 0) {&lt;br /&gt;
				_texCoords[i] = 0.0f;&lt;br /&gt;
				_texCoords[i+1] = 0.0f;&lt;br /&gt;
			}&lt;br /&gt;
			else {&lt;br /&gt;
				_texCoords[i] = 0.0f;&lt;br /&gt;
				_texCoords[i+1] = 1.0f;&lt;br /&gt;
			}&lt;br /&gt;
		}&lt;br /&gt;
		else {&lt;br /&gt;
			if (counter % 2 == 0) {&lt;br /&gt;
				_texCoords[i] = 1.0f;&lt;br /&gt;
				_texCoords[i+1] = 0.0f;&lt;br /&gt;
			}&lt;br /&gt;
			else {&lt;br /&gt;
				_texCoords[i] = 1.0f;&lt;br /&gt;
				_texCoords[i+1] = 1.0f;&lt;br /&gt;
			}&lt;br /&gt;
		}&lt;br /&gt;
		++counter;&lt;br /&gt;
		if (counter &amp;gt;= _gridSize) {&lt;br /&gt;
			++line;&lt;br /&gt;
			counter = 0;&lt;br /&gt;
		}&lt;br /&gt;
	}&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void DynamicGrid::generateTriangleIndices() &lt;br /&gt;
{&lt;br /&gt;
	_tIndices = new int[ _numTriangleIndices ];&lt;br /&gt;
	int counter = 0;&lt;br /&gt;
	int lineBreakCounter = 0;&lt;br /&gt;
	int counter3 = 0;&lt;br /&gt;
	for (int i=0; i&amp;lt;_numTriangleIndices; i+=3) {&lt;br /&gt;
		if (i%2 ==0) {&lt;br /&gt;
			_tIndices[i] = counter;&lt;br /&gt;
			_tIndices[i+1] = counter+1;&lt;br /&gt;
			_tIndices[i+2] = counter+_gridSize;&lt;br /&gt;
		}&lt;br /&gt;
		else {&lt;br /&gt;
			_tIndices[i] = counter + _gridSize;&lt;br /&gt;
			_tIndices[i+1] = counter + 1;&lt;br /&gt;
			_tIndices[i+2] = counter+_gridSize+1;&lt;br /&gt;
			++counter;&lt;br /&gt;
		}&lt;br /&gt;
		++lineBreakCounter;&lt;br /&gt;
		if (lineBreakCounter == _gridSize*2 - 2) {&lt;br /&gt;
			--counter;&lt;br /&gt;
			++counter3;&lt;br /&gt;
			lineBreakCounter = 0;&lt;br /&gt;
			counter = counter3*_gridSize;&lt;br /&gt;
		}&lt;br /&gt;
		//std::cout&amp;lt;&amp;lt;_tIndices[i]&amp;lt;&amp;lt;&amp;quot;/&amp;quot;&amp;lt;&amp;lt;_tIndices[i+1]&amp;lt;&amp;lt;&amp;quot;/&amp;quot;&amp;lt;&amp;lt;_tIndices[i+2]&amp;lt;&amp;lt;std::endl;&lt;br /&gt;
	}&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void DynamicGrid::update()&lt;br /&gt;
{&lt;br /&gt;
	removeCustomModelNode();&lt;br /&gt;
	delete[] _positions;&lt;br /&gt;
	_positions = 0;&lt;br /&gt;
	delete[] _normals;&lt;br /&gt;
	_normals = 0;&lt;br /&gt;
	generatePositions();&lt;br /&gt;
	generateNormals();&lt;br /&gt;
	addCustomModelNode(-1);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void DynamicGrid::saveGridToFile(std::string fileName_)&lt;br /&gt;
{&lt;br /&gt;
	//std::stringstream fName;&lt;br /&gt;
	//fName&amp;lt;&amp;lt;fileName_;&lt;br /&gt;
	//fName&amp;lt;&amp;lt;&amp;quot;.d2g&amp;quot;;&lt;br /&gt;
	std::stringstream ss;&lt;br /&gt;
	// magic header&lt;br /&gt;
	ss&amp;lt;&amp;lt;&amp;quot;D2SG\n&amp;quot;;&lt;br /&gt;
	// the gridsize (important to know!)&lt;br /&gt;
	ss&amp;lt;&amp;lt;_gridSize;&lt;br /&gt;
	ss&amp;lt;&amp;lt;&amp;quot;\n&amp;quot;;&lt;br /&gt;
	// the quadsize (important to know!)&lt;br /&gt;
	ss&amp;lt;&amp;lt;_size;&lt;br /&gt;
	ss&amp;lt;&amp;lt;&amp;quot;\n&amp;quot;;&lt;br /&gt;
	// number of coordinates (most important to know!)&lt;br /&gt;
	ss&amp;lt;&amp;lt;(_gridSize*_gridSize*3);&lt;br /&gt;
	ss&amp;lt;&amp;lt;&amp;quot;\n&amp;quot;;&lt;br /&gt;
	// coordinates&lt;br /&gt;
	for (int y=0; y&amp;lt;_gridSize; ++y) {&lt;br /&gt;
		for (int x=0; x&amp;lt;_gridSize; ++x) {&lt;br /&gt;
			ss&amp;lt;&amp;lt;_grid[y][x].x;&lt;br /&gt;
			ss&amp;lt;&amp;lt;&amp;quot;\n&amp;quot;;&lt;br /&gt;
			ss&amp;lt;&amp;lt;_grid[y][x].y;&lt;br /&gt;
			ss&amp;lt;&amp;lt;&amp;quot;\n&amp;quot;;&lt;br /&gt;
			ss&amp;lt;&amp;lt;_grid[y][x].z;&lt;br /&gt;
			ss&amp;lt;&amp;lt;&amp;quot;\n&amp;quot;;&lt;br /&gt;
		}&lt;br /&gt;
	}&lt;br /&gt;
	ss&amp;lt;&amp;lt;&amp;quot;\n&amp;quot;;&lt;br /&gt;
	std::ofstream dest(fileName_.c_str());&lt;br /&gt;
	if (dest.is_open()) {&lt;br /&gt;
		dest&amp;lt;&amp;lt;ss.str();&lt;br /&gt;
		dest.close();&lt;br /&gt;
	}&lt;br /&gt;
	std::cout&amp;lt;&amp;lt;&amp;quot;Grid successfully saved to file: &amp;quot;&amp;lt;&amp;lt;fileName_&amp;lt;&amp;lt;std::endl;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
bool DynamicGrid::readGridFromFile(std::string fileName_)&lt;br /&gt;
{&lt;br /&gt;
	int numCoordinates;&lt;br /&gt;
	std::ifstream inFile;&lt;br /&gt;
	inFile.open(fileName_.c_str());&lt;br /&gt;
	bool error = false;&lt;br /&gt;
	if (!inFile) {&lt;br /&gt;
		std::cout&amp;lt;&amp;lt;&amp;quot;Gridfile &amp;quot;&amp;lt;&amp;lt;fileName_&amp;lt;&amp;lt;&amp;quot; could not be found! Creating new grid.&amp;quot;&amp;lt;&amp;lt;std::endl;&lt;br /&gt;
		error = true;&lt;br /&gt;
	}&lt;br /&gt;
	else {&lt;br /&gt;
		std::string line;&lt;br /&gt;
		if (std::getline(inFile, line)) {&lt;br /&gt;
			std::cout&amp;lt;&amp;lt;&amp;quot;Line: &amp;quot;&amp;lt;&amp;lt;line&amp;lt;&amp;lt;std::endl;&lt;br /&gt;
			//if (!(line == &amp;quot;D2SG&amp;quot;)) {&lt;br /&gt;
			if (line.compare(&amp;quot;D2SG&amp;quot;) != 0){&lt;br /&gt;
				std::cout&amp;lt;&amp;lt;&amp;quot;wrong grid-file format &amp;quot;&amp;lt;&amp;lt;line.compare(&amp;quot;D2SG&amp;quot;)&amp;lt;&amp;lt;std::endl;&lt;br /&gt;
				error = true;&lt;br /&gt;
			}&lt;br /&gt;
			else {&lt;br /&gt;
				std::cout&amp;lt;&amp;lt;&amp;quot;Valid grid-file found!&amp;quot;&amp;lt;&amp;lt;std::endl;&lt;br /&gt;
			}&lt;br /&gt;
		}&lt;br /&gt;
		if (std::getline(inFile, line)) {&lt;br /&gt;
			_gridSize = stringToInt(line);&lt;br /&gt;
			//std::cout&amp;lt;&amp;lt;&amp;quot;gridsize: &amp;quot;&amp;lt;&amp;lt;_gridSize&amp;lt;&amp;lt;std::endl;&lt;br /&gt;
		}&lt;br /&gt;
		else {&lt;br /&gt;
			error = true;&lt;br /&gt;
		}&lt;br /&gt;
		if (std::getline(inFile, line)) {&lt;br /&gt;
			_size = stringToInt(line);&lt;br /&gt;
			//std::cout&amp;lt;&amp;lt;&amp;quot;quadsize: &amp;quot;&amp;lt;&amp;lt;_size&amp;lt;&amp;lt;std::endl;&lt;br /&gt;
		}&lt;br /&gt;
		else {&lt;br /&gt;
			error = true;&lt;br /&gt;
		}&lt;br /&gt;
		if (std::getline(inFile, line)) {&lt;br /&gt;
			numCoordinates = stringToInt(line);&lt;br /&gt;
			//std::cout&amp;lt;&amp;lt;&amp;quot;numCoords: &amp;quot;&amp;lt;&amp;lt;numCoordinates&amp;lt;&amp;lt;std::endl;&lt;br /&gt;
		}&lt;br /&gt;
		else {&lt;br /&gt;
			error = true;&lt;br /&gt;
		}&lt;br /&gt;
		if (!error) {&lt;br /&gt;
			_grid = new Vec3f*[_gridSize];&lt;br /&gt;
			for(int y=0; y&amp;lt;_gridSize; ++y) {&lt;br /&gt;
				_grid[y] = new Vec3f[_gridSize];&lt;br /&gt;
				for (int x=0; x&amp;lt;_gridSize; ++x) {&lt;br /&gt;
					Vec3f v;&lt;br /&gt;
					if (std::getline(inFile, line)) {&lt;br /&gt;
						v.x = stringToFloat(line);&lt;br /&gt;
					}&lt;br /&gt;
					if (std::getline(inFile, line)) {&lt;br /&gt;
						v.y = stringToFloat(line);&lt;br /&gt;
					}&lt;br /&gt;
					if (std::getline(inFile, line)) {&lt;br /&gt;
						v.z = stringToFloat(line);&lt;br /&gt;
					}&lt;br /&gt;
					_grid[y][x] = v;&lt;br /&gt;
				}&lt;br /&gt;
			}&lt;br /&gt;
		}&lt;br /&gt;
	}&lt;br /&gt;
	inFile.close();&lt;br /&gt;
	if (error) {&lt;br /&gt;
		_gridSize = GRIDSIZE;&lt;br /&gt;
		_size = 12;&lt;br /&gt;
		_grid = 0;&lt;br /&gt;
	}&lt;br /&gt;
	_numVertices = (_gridSize*_gridSize);&lt;br /&gt;
	_numTriangles = ((_gridSize - 1) * (_gridSize - 1)) * 2;&lt;br /&gt;
	_numTriangleIndices = _numTriangles * 3;&lt;br /&gt;
	_origin = Vec3f(-_size/2*_gridSize, 0, _size/2*_gridSize);&lt;br /&gt;
	return true;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
=Usage example=&lt;br /&gt;
&lt;br /&gt;
Finally this is all you have to do to generate the grid and display it in your scene.&lt;br /&gt;
{{CppSourceCode|&lt;br /&gt;
description= app.cpp| &lt;br /&gt;
code=&lt;br /&gt;
&amp;lt;source lang=&amp;quot;cpp&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
	// initialize a new grid (args: quadsize, model-name, filename (if applicable)&lt;br /&gt;
	_grid = new DynamicGrid(12.0f, &amp;quot;grid&amp;quot;, &amp;quot;grid-filename&amp;quot;);&lt;br /&gt;
	// do not forget to load a material and apply it to the mesh&lt;br /&gt;
	_grid-&amp;gt;setMaterial(gridMatRes);&lt;br /&gt;
	// generate the grid&lt;br /&gt;
	_grid-&amp;gt;generate();&lt;br /&gt;
	// add the grid-model to the RootNode&lt;br /&gt;
	_grid-&amp;gt;addCustomModelNode(RootNode);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
'''TODO'''&lt;/div&gt;</summary>
		<author><name>Wakko</name></author>	</entry>

	<entry>
		<id>http://horde3d.org/wiki/index.php?title=Procedurally_generated_geometry_tutorial&amp;diff=567</id>
		<title>Procedurally generated geometry tutorial</title>
		<link rel="alternate" type="text/html" href="http://horde3d.org/wiki/index.php?title=Procedurally_generated_geometry_tutorial&amp;diff=567"/>
				<updated>2009-10-26T11:46:43Z</updated>
		
		<summary type="html">&lt;p&gt;Wakko: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;'''Work in progress   - Due to the current changes in the Horde API this tutorial will be delayed '''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
= Important notes=&lt;br /&gt;
* The code used here has been tested with Horde3D 1.0.0 beta2 and beta3 and will '''NOT''' work with the latest release (beta4)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=Overview=&lt;br /&gt;
==Basic approach==&lt;br /&gt;
To create and display a procedurally generated mesh that, instead of being loaded from a Horde3D Scene node and a geoemtry file(*.scene.xml, *.geo), will be created in-memory by some algorithm, you have to create a mesh first and then &amp;quot;fake&amp;quot; the .geo-file and the scene node itself and pass it to the engine.&lt;br /&gt;
&lt;br /&gt;
To do that you have to create your procedural geometry first. This is easy for simple shapes like single triangles, squares or triangle-strips, but will become way more difficult when we try to generate complex meshes, e.g. when we have a cloud of points in 3D space and have to describe which points make triangles, and which don't (calculating the triangle indices, texture coordinates and normals).&lt;br /&gt;
&lt;br /&gt;
When we have calculated the geometry itself we need to create a char-stream to make Horde believe the geometry has been read from a file and pass it to Horde as a geometry Resource.&lt;br /&gt;
The final step is to create a Horde3D Scene Node from our procedurally generated mesh and render it into our scene.&lt;br /&gt;
[http://musicracer.de/images/Screenshot-1_small.jpg &lt;br /&gt;
This is how it could look like]&lt;br /&gt;
&lt;br /&gt;
=StreamGenerator=&lt;br /&gt;
&lt;br /&gt;
These classes are only for creating the character stream that will contain the geometry resource.&lt;br /&gt;
&lt;br /&gt;
{{CppSourceCode|&lt;br /&gt;
description= StreamGenerator.h| &lt;br /&gt;
code=&lt;br /&gt;
&amp;lt;source lang=&amp;quot;cpp&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
#pragma once&lt;br /&gt;
#include &amp;lt;sstream&amp;gt;&lt;br /&gt;
#include &amp;lt;string&amp;gt;&lt;br /&gt;
#include &amp;lt;iostream&amp;gt;&lt;br /&gt;
&lt;br /&gt;
class StreamGenerator &lt;br /&gt;
{&lt;br /&gt;
public:&lt;br /&gt;
	StreamGenerator();&lt;br /&gt;
	virtual ~StreamGenerator();&lt;br /&gt;
	virtual const char* getStream() = 0;&lt;br /&gt;
	virtual const int getStreamSize() = 0;&lt;br /&gt;
};&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{CppSourceCode|&lt;br /&gt;
description= StreamGenerator.cpp| &lt;br /&gt;
code=&lt;br /&gt;
&amp;lt;source lang=&amp;quot;cpp&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;quot;StreamGenerator.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
StreamGenerator::StreamGenerator() &lt;br /&gt;
{&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
StreamGenerator::~StreamGenerator()&lt;br /&gt;
{&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{CppSourceCode|&lt;br /&gt;
description= GeometryStreamGenerator.h| &lt;br /&gt;
code=&lt;br /&gt;
&amp;lt;source lang=&amp;quot;cpp&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
#pragma once&lt;br /&gt;
#include &amp;quot;StreamGenerator.h&amp;quot;&lt;br /&gt;
#include &amp;quot;CustomGeometry.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
class GeometryStreamGenerator : public StreamGenerator&lt;br /&gt;
{&lt;br /&gt;
private:&lt;br /&gt;
	std::stringstream* ss;&lt;br /&gt;
	void generate();&lt;br /&gt;
	int numVertices, numTriangleIndices;&lt;br /&gt;
	char* _stream;&lt;br /&gt;
	CustomGeometry* _geom;&lt;br /&gt;
&lt;br /&gt;
public:&lt;br /&gt;
	GeometryStreamGenerator(CustomGeometry* geom_);&lt;br /&gt;
	~GeometryStreamGenerator();&lt;br /&gt;
	const char* getStream();&lt;br /&gt;
	const std::stringstream* getStringStream() { return ss; };&lt;br /&gt;
	const int getStreamSize();&lt;br /&gt;
	const int getNumVertices();&lt;br /&gt;
	const int getNumTriangleIndices();&lt;br /&gt;
	void release();&lt;br /&gt;
};&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{CppSourceCode|&lt;br /&gt;
description= GeometryStreamGenerator.cpp| &lt;br /&gt;
code=&lt;br /&gt;
&amp;lt;source lang=&amp;quot;cpp&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;quot;GeometryStreamGenerator.h&amp;quot;&lt;br /&gt;
#include &amp;quot;time.h&amp;quot;&lt;br /&gt;
#include &amp;quot;utMath.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
GeometryStreamGenerator::GeometryStreamGenerator(CustomGeometry* geom_) : _geom(geom_)&lt;br /&gt;
{&lt;br /&gt;
	ss = new std::stringstream();&lt;br /&gt;
	generate();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
GeometryStreamGenerator::~GeometryStreamGenerator()&lt;br /&gt;
{&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void GeometryStreamGenerator::generate()&lt;br /&gt;
{&lt;br /&gt;
	numVertices = _geom-&amp;gt;getNumVertices();&lt;br /&gt;
	numTriangleIndices = _geom-&amp;gt;getNumTriangleIndices();&lt;br /&gt;
	const std::string _magicHeader = &amp;quot;H3DG&amp;quot;;&lt;br /&gt;
	const int _version = 5;&lt;br /&gt;
	const int _numJoints = 1;&lt;br /&gt;
	const float _identityMatrix[] = {	1.0f, 0.0f, 0.0f, 0.0f,  &lt;br /&gt;
						0.0f, 1.0f, 0.0f, 0.0f,  &lt;br /&gt;
						0.0f, 0.0f, 1.0f, 0.0f,  &lt;br /&gt;
						0.0f, 0.0f, 0.0f, 1.0f};&lt;br /&gt;
	const int _numVertexStreams = 3;&lt;br /&gt;
	const int _magicVertices = 0;&lt;br /&gt;
	const int _vertexStreamElementSize = 12;&lt;br /&gt;
	const float* _positions = _geom-&amp;gt;getPositions();&lt;br /&gt;
	const int _magicNormals = 1;&lt;br /&gt;
	const int _normalsStreamElementSize = 6;&lt;br /&gt;
	const float* _normals = _geom-&amp;gt;getNormals();&lt;br /&gt;
	const int _magicTextureCoords1 = 6;&lt;br /&gt;
	const int _texCoordStreamElementSize = 8;&lt;br /&gt;
	const float* _texCoords = _geom-&amp;gt;getTexCoords();&lt;br /&gt;
	const int* _triangleIndices = _geom-&amp;gt;getTriangleIndices();&lt;br /&gt;
	const int _numMorphTragets = 0;&lt;br /&gt;
	// header&lt;br /&gt;
	ss-&amp;gt;write(_magicHeader.c_str(), 4*sizeof(char));&lt;br /&gt;
	ss-&amp;gt;write((char*)&amp;amp;_version, sizeof(int));&lt;br /&gt;
	// joints (mandatory)&lt;br /&gt;
	ss-&amp;gt;write((char*)&amp;amp;_numJoints, sizeof(int));&lt;br /&gt;
	for (int i=0; i&amp;lt;16; ++i) {&lt;br /&gt;
		ss-&amp;gt;write((char*)&amp;amp;_identityMatrix[i], sizeof(float));&lt;br /&gt;
	}&lt;br /&gt;
	// vertices&lt;br /&gt;
	ss-&amp;gt;write((char*)&amp;amp;_numVertexStreams, sizeof(int));&lt;br /&gt;
	const int numVerts = _geom-&amp;gt;getNumVertices();&lt;br /&gt;
	ss-&amp;gt;write((char*)&amp;amp;numVerts, sizeof(int));&lt;br /&gt;
	ss-&amp;gt;write((char*)&amp;amp;_magicVertices, sizeof(int));&lt;br /&gt;
	ss-&amp;gt;write((char*)&amp;amp;_vertexStreamElementSize, sizeof(int));&lt;br /&gt;
	for (int i=0; i&amp;lt;_geom-&amp;gt;getNumVertices()*3; ++i) {&lt;br /&gt;
		ss-&amp;gt;write((char*)&amp;amp;_positions[i], sizeof(float));&lt;br /&gt;
	}&lt;br /&gt;
	// normals&lt;br /&gt;
	ss-&amp;gt;write((char*)&amp;amp;_magicNormals, sizeof(int));&lt;br /&gt;
	ss-&amp;gt;write((char*)&amp;amp;_normalsStreamElementSize, sizeof(int));&lt;br /&gt;
	for (int i=0; i&amp;lt;_geom-&amp;gt;getNumVertices()*3; ++i) {&lt;br /&gt;
		// do not forget to mutliply the value with 32767 and &lt;br /&gt;
		// then convert it to short before writing to the stream&lt;br /&gt;
		const short f = (short)(_normals[i]*32767);&lt;br /&gt;
		ss-&amp;gt;write((char*)&amp;amp;f, sizeof(short));&lt;br /&gt;
	}&lt;br /&gt;
	// texture coordinates&lt;br /&gt;
	ss-&amp;gt;write((char*)&amp;amp;_magicTextureCoords1, sizeof(int));&lt;br /&gt;
	ss-&amp;gt;write((char*)&amp;amp;_texCoordStreamElementSize, sizeof(int));&lt;br /&gt;
	for (int i=0; i&amp;lt;_geom-&amp;gt;getNumVertices()*2; ++i) {&lt;br /&gt;
		ss-&amp;gt;write((char*)&amp;amp;_texCoords[i], sizeof(float));&lt;br /&gt;
	}&lt;br /&gt;
	// triangle indices&lt;br /&gt;
	const int numTriangleIndices = _geom-&amp;gt;getNumTriangleIndices();&lt;br /&gt;
	ss-&amp;gt;write((char*)&amp;amp;numTriangleIndices, sizeof(int));&lt;br /&gt;
	for (int i=0; i&amp;lt;_geom-&amp;gt;getNumTriangleIndices(); ++i) {&lt;br /&gt;
		ss-&amp;gt;write((char*)&amp;amp;_triangleIndices[i], sizeof(int));&lt;br /&gt;
	}&lt;br /&gt;
	ss-&amp;gt;write((char*)&amp;amp;_numMorphTragets, sizeof(int));&lt;br /&gt;
	_stream = new char[ss-&amp;gt;tellp()];&lt;br /&gt;
	ss-&amp;gt;read(_stream, ss-&amp;gt;tellp());&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
const char* GeometryStreamGenerator::getStream()&lt;br /&gt;
{&lt;br /&gt;
	return _stream;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
const int GeometryStreamGenerator::getStreamSize() &lt;br /&gt;
{&lt;br /&gt;
	int t = (int)ss-&amp;gt;tellp();&lt;br /&gt;
	return t;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
const int GeometryStreamGenerator::getNumVertices()&lt;br /&gt;
{&lt;br /&gt;
	return numVertices;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
const int GeometryStreamGenerator::getNumTriangleIndices()&lt;br /&gt;
{&lt;br /&gt;
	return numTriangleIndices;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void GeometryStreamGenerator::release()&lt;br /&gt;
{&lt;br /&gt;
	ss-&amp;gt;flush();&lt;br /&gt;
	ss-&amp;gt;clear();&lt;br /&gt;
	delete ss;&lt;br /&gt;
	ss = 0;&lt;br /&gt;
	delete[] _stream;&lt;br /&gt;
	_stream = 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
=CustomGeometry base class=&lt;br /&gt;
&lt;br /&gt;
Base class for the custom geometry. This class currently contains lots of deprecated stuff, e.g. the update() function. This function was used to update an in-memory gemoetry resource in the &amp;quot;punk-rock&amp;quot;-way. Until Horde3D Beta3 the geometry resources were read-only, so directmanipulation of vertices was impossible. To modify the vertices I had to unload the geometry resource, re-create it with the new vertex-positions and load it into Horde again. '''This is not necessary any more because since Beta4 the geometry resources are not read-only anymore.'''&lt;br /&gt;
&lt;br /&gt;
All custom geometry classes should be derived from this class and implement the abstract functions as needed. (See the examples below)&lt;br /&gt;
&lt;br /&gt;
{{CppSourceCode|&lt;br /&gt;
description= CustomGeometry.h| &lt;br /&gt;
code=&lt;br /&gt;
&amp;lt;source lang=&amp;quot;cpp&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
#pragma once&lt;br /&gt;
/**&lt;br /&gt;
 * Abstract class for custom/dynamic geometry&lt;br /&gt;
 **/&lt;br /&gt;
#include &amp;quot;utMath.h&amp;quot;&lt;br /&gt;
#include &amp;quot;Horde3D.h&amp;quot;&lt;br /&gt;
#include &amp;lt;string&amp;gt;&lt;br /&gt;
&lt;br /&gt;
class CustomGeometry &lt;br /&gt;
{&lt;br /&gt;
protected:&lt;br /&gt;
	float _size;&lt;br /&gt;
	Vec3f _origin;&lt;br /&gt;
	int _numVertices;&lt;br /&gt;
	int _numTriangles;&lt;br /&gt;
	int _numTriangleIndices;&lt;br /&gt;
	float* _positions;&lt;br /&gt;
	float* _normals;&lt;br /&gt;
	float* _texCoords;&lt;br /&gt;
	int* _tIndices;&lt;br /&gt;
	std::string _name;&lt;br /&gt;
	NodeHandle _model;&lt;br /&gt;
	NodeHandle _parent;&lt;br /&gt;
	ResHandle _material;&lt;br /&gt;
	virtual void generatePositions() = 0;&lt;br /&gt;
	virtual void generateNormals() = 0;&lt;br /&gt;
	virtual void generateTexCoords() = 0;&lt;br /&gt;
	virtual void generateTriangleIndices() = 0;&lt;br /&gt;
&lt;br /&gt;
public:&lt;br /&gt;
	CustomGeometry();&lt;br /&gt;
	virtual void generate() = 0;&lt;br /&gt;
	const int getNumVertices() { return _numVertices; }&lt;br /&gt;
	const float* getPositions() { return _positions; }&lt;br /&gt;
	const float* getNormals() { return _normals; }&lt;br /&gt;
	const float* getTexCoords() { return _texCoords; }&lt;br /&gt;
	const int* getTriangleIndices() { return _tIndices; }&lt;br /&gt;
	const int getNumTriangles() { return _numTriangles; }&lt;br /&gt;
	const int getNumTriangleIndices() { return _numTriangleIndices; }&lt;br /&gt;
	void release();&lt;br /&gt;
	const Vec3f getInterpolatedNormal(Vec3f n1_, Vec3f n2_);&lt;br /&gt;
	// pass -1 as the parameter to leave the parent node unchanged&lt;br /&gt;
	void addCustomModelNode(NodeHandle parent_);&lt;br /&gt;
	bool removeCustomModelNode();&lt;br /&gt;
	void setMaterial(ResHandle material_) { _material = material_; }&lt;br /&gt;
	void setParent(NodeHandle parent_) { _parent = parent_; }&lt;br /&gt;
	NodeHandle getModel() { return _model; }&lt;br /&gt;
	ResHandle getMaterial() { return _material; }&lt;br /&gt;
	void update();&lt;br /&gt;
	Vec3f getOrigin() { return _origin; }&lt;br /&gt;
	void setOrigin(Vec3f origin_) { _origin = origin_; }&lt;br /&gt;
	const float getSize() { return _size; }&lt;br /&gt;
};&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{CppSourceCode|&lt;br /&gt;
description= CustomGeometry.cpp| &lt;br /&gt;
code=&lt;br /&gt;
&amp;lt;source lang=&amp;quot;cpp&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;quot;CustomGeometry.h&amp;quot;&lt;br /&gt;
#include &amp;lt;iostream&amp;gt;&lt;br /&gt;
#include &amp;lt;string&amp;gt;&lt;br /&gt;
#include &amp;lt;sstream&amp;gt;&lt;br /&gt;
#include &amp;lt;fstream&amp;gt;&lt;br /&gt;
#include &amp;quot;GeometryStreamGenerator.h&amp;quot;&lt;br /&gt;
#include &amp;quot;Horde3DUtils.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
CustomGeometry::CustomGeometry() : _name(&amp;quot;default&amp;quot;), _size(1)&lt;br /&gt;
{&lt;br /&gt;
	_origin = Vec3f(0, 0, 0);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void CustomGeometry::release()&lt;br /&gt;
{&lt;br /&gt;
	delete[] _positions;&lt;br /&gt;
	_positions = 0;&lt;br /&gt;
	delete[] _normals;&lt;br /&gt;
	_normals = 0;&lt;br /&gt;
	delete[] _texCoords;&lt;br /&gt;
	_texCoords = 0;&lt;br /&gt;
	delete[] _tIndices;&lt;br /&gt;
	_tIndices = 0;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
const Vec3f CustomGeometry::getInterpolatedNormal(Vec3f n1_, Vec3f n2_) &lt;br /&gt;
{&lt;br /&gt;
	Vec3f newNormal = n1_ + n2_;&lt;br /&gt;
	float length = newNormal.length();&lt;br /&gt;
	return newNormal/length;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void CustomGeometry::addCustomModelNode(NodeHandle parent_)&lt;br /&gt;
{&lt;br /&gt;
	//std::stringstream* sa = new std::stringstream();&lt;br /&gt;
	std::stringstream ss;&lt;br /&gt;
	if (parent_ != -1) &lt;br /&gt;
		_parent = parent_;&lt;br /&gt;
	ss&amp;lt;&amp;lt; &amp;quot;customGeometry-&amp;quot;;&lt;br /&gt;
	ss&amp;lt;&amp;lt;_name;&lt;br /&gt;
	GeometryStreamGenerator* gsg = new GeometryStreamGenerator(this);&lt;br /&gt;
	ResHandle customGeoRes = Horde3D::addResource(ResourceTypes::Geometry, ss.str().c_str(), 0);&lt;br /&gt;
	Horde3D::loadResource(customGeoRes, gsg-&amp;gt;getStream(), gsg-&amp;gt;getStreamSize());&lt;br /&gt;
	// model_node_name&lt;br /&gt;
	ss&amp;lt;&amp;lt;&amp;quot;-Node&amp;quot;;&lt;br /&gt;
	_model = Horde3D::addModelNode(_parent, ss.str().c_str(), customGeoRes);&lt;br /&gt;
	// mesh_name&lt;br /&gt;
	ss&amp;lt;&amp;lt;&amp;quot;-Mesh&amp;quot;;&lt;br /&gt;
	Horde3D::addMeshNode(_model, ss.str().c_str(), _material, 0, gsg-&amp;gt;getNumTriangleIndices(), 0, gsg-&amp;gt;getNumVertices()-1);&lt;br /&gt;
	Horde3DUtils::dumpMessages();&lt;br /&gt;
	ss.str(&amp;quot;&amp;quot;);&lt;br /&gt;
	ss.clear();&lt;br /&gt;
	ss.flush();&lt;br /&gt;
	gsg-&amp;gt;release();&lt;br /&gt;
	delete gsg;&lt;br /&gt;
	gsg = 0;&lt;br /&gt;
	//Horde3D::setNodeTransform(_model, _origin.x, _origin.y, _origin.z, 0, 0, 0, 1, 1, 1);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
bool CustomGeometry::removeCustomModelNode()&lt;br /&gt;
{&lt;br /&gt;
	std::stringstream* ss = new std::stringstream();&lt;br /&gt;
	*ss&amp;lt;&amp;lt; &amp;quot;customGeometry-&amp;quot;;&lt;br /&gt;
	*ss&amp;lt;&amp;lt;_name;&lt;br /&gt;
	ResHandle rh = Horde3D::findResource(ResourceTypes::Geometry, ss-&amp;gt;str().c_str());&lt;br /&gt;
	if (Horde3D::isResourceLoaded(rh)) {&lt;br /&gt;
		Horde3D::removeResource(rh);&lt;br /&gt;
		Horde3D::unloadResource(rh);&lt;br /&gt;
		Horde3D::removeNode(_model);&lt;br /&gt;
		Horde3D::releaseUnusedResources();&lt;br /&gt;
		Horde3DUtils::dumpMessages();&lt;br /&gt;
		delete ss;&lt;br /&gt;
		return true;&lt;br /&gt;
	}&lt;br /&gt;
	else &lt;br /&gt;
		return false;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void CustomGeometry::update()&lt;br /&gt;
{&lt;br /&gt;
	removeCustomModelNode();&lt;br /&gt;
	addCustomModelNode(-1);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
=Simple Square=&lt;br /&gt;
&lt;br /&gt;
A simple two-sided (hard-coded) square. This is pretty straight forward and demonstrates how to derive from the CustomGeometry class and how the triangle indices work.&lt;br /&gt;
&lt;br /&gt;
{{CppSourceCode|&lt;br /&gt;
description= DynamicSquare.h| &lt;br /&gt;
code=&lt;br /&gt;
&amp;lt;source lang=&amp;quot;cpp&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
/**&lt;br /&gt;
 * Class representing a square &lt;br /&gt;
 **/&lt;br /&gt;
#pragma once&lt;br /&gt;
#include &amp;quot;CustomGeometry.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
class DynamicSquare : public CustomGeometry&lt;br /&gt;
{&lt;br /&gt;
protected:&lt;br /&gt;
	virtual void generatePositions();&lt;br /&gt;
	virtual void generateNormals();&lt;br /&gt;
	virtual void generateTexCoords();&lt;br /&gt;
	virtual void generateTriangleIndices();&lt;br /&gt;
&lt;br /&gt;
public:&lt;br /&gt;
	DynamicSquare();&lt;br /&gt;
	virtual void generate();&lt;br /&gt;
	DynamicSquare(const float size_, const std::string name_);&lt;br /&gt;
};&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{CppSourceCode|&lt;br /&gt;
description= DynamicSquare.cpp| &lt;br /&gt;
code=&lt;br /&gt;
&amp;lt;source lang=&amp;quot;cpp&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;quot;DynamicSquare.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
DynamicSquare::DynamicSquare() : CustomGeometry()&lt;br /&gt;
{&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
DynamicSquare::DynamicSquare(const float size_, const std::string name_) &lt;br /&gt;
{&lt;br /&gt;
	_size = size_;&lt;br /&gt;
	_name = name_;&lt;br /&gt;
	_numVertices = 8;&lt;br /&gt;
	_numTriangles = 4;&lt;br /&gt;
	_numTriangleIndices = (_numVertices - 2) * 3;&lt;br /&gt;
	//generate();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void DynamicSquare::generate() &lt;br /&gt;
{&lt;br /&gt;
	generatePositions();&lt;br /&gt;
	generateNormals();&lt;br /&gt;
	generateTexCoords();&lt;br /&gt;
	generateTriangleIndices();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void DynamicSquare::generatePositions() &lt;br /&gt;
{&lt;br /&gt;
	_positions = new float[_numVertices * 3 * 2];&lt;br /&gt;
	// front left point (x/y/z)&lt;br /&gt;
	_positions[0] = _origin.x * _size - _size/2;&lt;br /&gt;
	_positions[1] = _origin.y;&lt;br /&gt;
	_positions[2] = _origin.z * _size -_size/2;&lt;br /&gt;
	// front right point (x/y/z)&lt;br /&gt;
	_positions[3] = _origin.x * _size + _size/2;&lt;br /&gt;
	_positions[4] = _origin.y;&lt;br /&gt;
	_positions[5] = _origin.z * _size - _size/2;&lt;br /&gt;
	// back left point (x/y/z)&lt;br /&gt;
	_positions[6] = _origin.x * _size - _size/2;&lt;br /&gt;
	_positions[7] = _origin.y;&lt;br /&gt;
	_positions[8] = _origin.z * _size + _size/2;&lt;br /&gt;
	// back right point (x/y/z)&lt;br /&gt;
	_positions[9] = _origin.x * _size + _size/2;&lt;br /&gt;
	_positions[10] = _origin.y;&lt;br /&gt;
	_positions[11] = _origin.z * _size + _size/2;&lt;br /&gt;
&lt;br /&gt;
        // comment the bottom side if you do not want to have a two-sided sq&lt;br /&gt;
	// bottom sideuare&lt;br /&gt;
	// front left point (x/y/z)&lt;br /&gt;
	_positions[12] = _origin.x * _size - _size/2;&lt;br /&gt;
	_positions[13] = _origin.y-0.5;&lt;br /&gt;
	_positions[14] = _origin.z * _size - _size/2;&lt;br /&gt;
	// front right point (x/y/z)&lt;br /&gt;
	_positions[15] = _origin.x * _size + _size/2;&lt;br /&gt;
	_positions[16] = _origin.y-0.5;&lt;br /&gt;
	_positions[17] = _origin.z * _size - _size/2;&lt;br /&gt;
	// back left point (x/y/z)&lt;br /&gt;
	_positions[18] = _origin.x * _size - _size/2;&lt;br /&gt;
	_positions[19] = _origin.y-0.5;&lt;br /&gt;
	_positions[20] = _origin.z * _size + _size/2;&lt;br /&gt;
	// back right point (x/y/z)&lt;br /&gt;
	_positions[21] = _origin.x * _size + _size/2;&lt;br /&gt;
	_positions[22] = _origin.y-0.5;&lt;br /&gt;
	_positions[23] = _origin.z * _size + _size/2;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void DynamicSquare::generateNormals() &lt;br /&gt;
{&lt;br /&gt;
	_normals = new float[_numVertices * 3*2];&lt;br /&gt;
	for (int i=0; i&amp;lt; 12; i+=3) {&lt;br /&gt;
		_normals[i] = 0;&lt;br /&gt;
		_normals[i+1] = 1;&lt;br /&gt;
		_normals[i+2] = 0;&lt;br /&gt;
	}&lt;br /&gt;
	for (int i=13; i&amp;lt; 24; i+=3) {&lt;br /&gt;
		_normals[i] = 0;&lt;br /&gt;
		_normals[i+1] = -1;&lt;br /&gt;
		_normals[i+2] = 0;&lt;br /&gt;
	}&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void DynamicSquare::generateTexCoords()&lt;br /&gt;
{&lt;br /&gt;
	_texCoords = new float[_numVertices * 2 * 2];&lt;br /&gt;
	_texCoords[0] = 0.0f; &lt;br /&gt;
	_texCoords[1] = 0.0f;&lt;br /&gt;
	_texCoords[2] = 1.0f; &lt;br /&gt;
	_texCoords[3] = 0.0f;&lt;br /&gt;
	_texCoords[4] = 0.0f; &lt;br /&gt;
	_texCoords[5] = 1.0f;&lt;br /&gt;
	_texCoords[6] = 1.0f; &lt;br /&gt;
	_texCoords[7] = 1.0f;&lt;br /&gt;
	_texCoords[8] = 0.0f; &lt;br /&gt;
	_texCoords[9] = 0.0f;&lt;br /&gt;
	_texCoords[10] = 1.0f; &lt;br /&gt;
	_texCoords[11] = 0.0f;&lt;br /&gt;
	_texCoords[12] = 0.0f; &lt;br /&gt;
	_texCoords[13] = 1.0f;&lt;br /&gt;
	_texCoords[14] = 1.0f; &lt;br /&gt;
	_texCoords[15] = 1.0f;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void DynamicSquare::generateTriangleIndices() &lt;br /&gt;
{&lt;br /&gt;
	_tIndices = new int[_numTriangleIndices ];&lt;br /&gt;
	_tIndices[0] = 0;&lt;br /&gt;
	_tIndices[1] = 2;&lt;br /&gt;
	_tIndices[2] = 1;&lt;br /&gt;
	_tIndices[3] = 1;&lt;br /&gt;
	_tIndices[4] = 2;&lt;br /&gt;
	_tIndices[5] = 3;&lt;br /&gt;
	_tIndices[6] = 5;&lt;br /&gt;
	_tIndices[7] = 7;&lt;br /&gt;
	_tIndices[8] = 6;&lt;br /&gt;
	_tIndices[9] = 6;&lt;br /&gt;
	_tIndices[10] = 4;&lt;br /&gt;
	_tIndices[11] = 5;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
=Simple Grid=&lt;br /&gt;
&lt;br /&gt;
All the work above was made to create my own interactive terrain generator(screenshot on top of this page) for a A* pathfinding demonstrator. The Grid-class actually generates a 2-dimensional array of Vec3f(s) and allows to extrude each point and re-generate the mesh in realtime. The internal representation is writeable and in case of a change of any point the overridden update() function will be called to update the Horde3D geometry resource.&lt;br /&gt;
&lt;br /&gt;
[http://musicracer.de/images/grid_01_english.png&lt;br /&gt;
This is how it looks internally]&lt;br /&gt;
{{CppSourceCode|&lt;br /&gt;
description= DynamicGrid.h| &lt;br /&gt;
code=&lt;br /&gt;
&amp;lt;source lang=&amp;quot;cpp&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
/**&lt;br /&gt;
 * Class representing a grid&lt;br /&gt;
 **/&lt;br /&gt;
#pragma once&lt;br /&gt;
#include &amp;quot;CustomGeometry.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
class DynamicGrid : public CustomGeometry&lt;br /&gt;
{&lt;br /&gt;
protected:&lt;br /&gt;
	virtual void generatePositions();&lt;br /&gt;
	virtual void generateNormals();&lt;br /&gt;
	virtual void generateTexCoords();&lt;br /&gt;
	virtual void generateTriangleIndices();&lt;br /&gt;
       // generate the internal representation of the grid (writeable to allow updates of single points!)&lt;br /&gt;
	void generateGrid();&lt;br /&gt;
	int _gridSize;&lt;br /&gt;
	Vec3f** _grid;&lt;br /&gt;
	std::string _fileName;&lt;br /&gt;
&lt;br /&gt;
public:&lt;br /&gt;
	DynamicGrid();&lt;br /&gt;
	virtual void generate();&lt;br /&gt;
	DynamicGrid(const float size_, const std::string name_, std::string fileName_);&lt;br /&gt;
	Vec3f getPointAt(int x_, int y_) { return _grid[y_][x_]; }&lt;br /&gt;
	void setPointAt(int x_, int y_, Vec3f newPos_) { _grid[y_][x_] = newPos_; }&lt;br /&gt;
	int getGridSize() { return _gridSize; }&lt;br /&gt;
	// overwrite update() from parent class&lt;br /&gt;
	void update();&lt;br /&gt;
	void saveGridToFile(std::string fileName_);&lt;br /&gt;
	bool readGridFromFile(std::string fileName_);&lt;br /&gt;
&lt;br /&gt;
};&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{CppSourceCode|&lt;br /&gt;
description= DynamicGrid.cpp| &lt;br /&gt;
code=&lt;br /&gt;
&amp;lt;source lang=&amp;quot;cpp&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;quot;DynamicGrid.h&amp;quot;&lt;br /&gt;
#include &amp;quot;rng.h&amp;quot;&lt;br /&gt;
#include &amp;lt;iostream&amp;gt;&lt;br /&gt;
#include &amp;lt;string&amp;gt;&lt;br /&gt;
#include &amp;lt;sstream&amp;gt;&lt;br /&gt;
#include &amp;lt;fstream&amp;gt;&lt;br /&gt;
#include &amp;quot;util.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
#define GRIDSIZE 50&lt;br /&gt;
&lt;br /&gt;
DynamicGrid::DynamicGrid() : CustomGeometry()&lt;br /&gt;
{&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
DynamicGrid::DynamicGrid(const float size_, const std::string name_, std::string fileName_) : _fileName(fileName_) &lt;br /&gt;
{&lt;br /&gt;
	_name = name_;&lt;br /&gt;
	_positions = 0;&lt;br /&gt;
	_normals = 0;&lt;br /&gt;
	_texCoords = 0;&lt;br /&gt;
	_tIndices = 0;&lt;br /&gt;
	readGridFromFile(_fileName);&lt;br /&gt;
	_numVertices = (_gridSize*_gridSize);&lt;br /&gt;
	_numTriangles = ((_gridSize - 1) * (_gridSize - 1)) * 2;&lt;br /&gt;
	_numTriangleIndices = _numTriangles * 3;&lt;br /&gt;
	_origin = Vec3f(-_size/2*_gridSize, 0, _size/2*_gridSize);&lt;br /&gt;
	/*&lt;br /&gt;
	std::cout&amp;lt;&amp;lt;&amp;quot;numVerts: &amp;quot;&amp;lt;&amp;lt;_numVertices&amp;lt;&amp;lt;std::endl;&lt;br /&gt;
	std::cout&amp;lt;&amp;lt;&amp;quot;numTris: &amp;quot;&amp;lt;&amp;lt;_numTriangles&amp;lt;&amp;lt;std::endl;&lt;br /&gt;
	std::cout&amp;lt;&amp;lt;&amp;quot;numTInds: &amp;quot;&amp;lt;&amp;lt;_numTriangleIndices&amp;lt;&amp;lt;std::endl;&lt;br /&gt;
	std::cout&amp;lt;&amp;lt;&amp;quot;size: &amp;quot;&amp;lt;&amp;lt;_size&amp;lt;&amp;lt;std::endl;&lt;br /&gt;
	*/&lt;br /&gt;
	//std::cout&amp;lt;&amp;lt;_origin.x&amp;lt;&amp;lt;&amp;quot;/&amp;quot;&amp;lt;&amp;lt;_origin.y&amp;lt;&amp;lt;&amp;quot;/&amp;quot;&amp;lt;&amp;lt;_origin.z&amp;lt;&amp;lt;std::endl;&lt;br /&gt;
	//generate();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void DynamicGrid::generate() &lt;br /&gt;
{&lt;br /&gt;
	if (!_grid)&lt;br /&gt;
		generateGrid();&lt;br /&gt;
	generatePositions();&lt;br /&gt;
	generateNormals();&lt;br /&gt;
	generateTexCoords();&lt;br /&gt;
	generateTriangleIndices();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// the following two functions could be combined into one single loop, but I left it this way for clarity...&lt;br /&gt;
void DynamicGrid::generateGrid()&lt;br /&gt;
{&lt;br /&gt;
	RNG rng;&lt;br /&gt;
	_grid = new Vec3f*[_gridSize];&lt;br /&gt;
	for (int y=0; y&amp;lt;_gridSize; ++y) {&lt;br /&gt;
		_grid[y] = new Vec3f[_gridSize];&lt;br /&gt;
		for (int x=0; x&amp;lt;_gridSize; ++x) {&lt;br /&gt;
			long rand = (abs((int)rng.rand_int31()) %3);&lt;br /&gt;
			_grid[y][x] = Vec3f(_origin.x/2+_size/2*x, rand, _origin.z/2-_size/2*y);&lt;br /&gt;
			//std::cout&amp;lt;&amp;lt;_grid[y][x].x&amp;lt;&amp;lt;&amp;quot;/&amp;quot;&amp;lt;&amp;lt;_grid[y][x].y&amp;lt;&amp;lt;&amp;quot;/&amp;quot;&amp;lt;&amp;lt;_grid[y][x].z&amp;lt;&amp;lt;std::endl;&lt;br /&gt;
		}&lt;br /&gt;
	}&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void DynamicGrid::generatePositions() &lt;br /&gt;
{&lt;br /&gt;
	_positions = new float[_numVertices*3];&lt;br /&gt;
	int counter = 0;&lt;br /&gt;
	for (int i=0; i&amp;lt;_numVertices*3; i+=3) {&lt;br /&gt;
		int y = counter / _gridSize;&lt;br /&gt;
		int x = counter % _gridSize;&lt;br /&gt;
		_positions[i] = _grid[y][x].x;&lt;br /&gt;
		_positions[i+1] = _grid[y][x].y;&lt;br /&gt;
		_positions[i+2] = _grid[y][x].z;&lt;br /&gt;
		++counter;&lt;br /&gt;
	}&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void DynamicGrid::generateNormals() &lt;br /&gt;
{&lt;br /&gt;
	_normals = new float[_numVertices * 3];&lt;br /&gt;
	for (int i=0; i&amp;lt; _numVertices*3; i+=3) {&lt;br /&gt;
		int pos = i/3;&lt;br /&gt;
		int xPos = pos % _gridSize;&lt;br /&gt;
		int yPos = pos / _gridSize;&lt;br /&gt;
		Vec3f xPred;&lt;br /&gt;
		Vec3f xSucc;&lt;br /&gt;
		Vec3f yPred;&lt;br /&gt;
		Vec3f ySucc;&lt;br /&gt;
		Vec3f normal;&lt;br /&gt;
		if (xPos &amp;gt; 0 &amp;amp;&amp;amp; yPos &amp;gt; 0) {&lt;br /&gt;
			// if the current vertex is inside the grid we will calculate&lt;br /&gt;
			// two normals from the previous&amp;amp;next point and our current vertex&lt;br /&gt;
			if (xPos &amp;lt; _gridSize-1 &amp;amp;&amp;amp; yPos &amp;lt; _gridSize-1) {&lt;br /&gt;
				xSucc = _grid[yPos][xPos+1];&lt;br /&gt;
				xPred = _grid[yPos][xPos-1];&lt;br /&gt;
				ySucc = _grid[yPos+1][xPos];&lt;br /&gt;
				yPred = _grid[yPos-1][xPos];&lt;br /&gt;
				Vec3f v1 = xSucc - _grid[yPos][xPos];&lt;br /&gt;
				if (v1.y &amp;lt; 0)&lt;br /&gt;
					v1.y *= -1;&lt;br /&gt;
				Vec3f v2 = xPred - _grid[yPos][xPos];&lt;br /&gt;
				if (v2.y &amp;lt; 0)&lt;br /&gt;
					v2.y *= -1;&lt;br /&gt;
				v1 += v2;&lt;br /&gt;
				Vec3f v3 = ySucc - _grid[yPos][xPos];&lt;br /&gt;
				if (v3.y &amp;lt; 0)&lt;br /&gt;
					v3.y *= -1;&lt;br /&gt;
				Vec3f v4 = yPred - _grid[yPos][xPos];&lt;br /&gt;
				if (v4.y &amp;lt; 0)&lt;br /&gt;
					v4.y *= -1;&lt;br /&gt;
				v3 += v4;&lt;br /&gt;
				normal = getInterpolatedNormal(v1, v3);&lt;br /&gt;
			}&lt;br /&gt;
			// if the vertex is on the grid's border the normal will simply be 0/1/0&lt;br /&gt;
			else {&lt;br /&gt;
				normal = Vec3f(0,1,0);&lt;br /&gt;
			}&lt;br /&gt;
		}&lt;br /&gt;
		else {&lt;br /&gt;
			normal = Vec3f(0,1,0);&lt;br /&gt;
		}&lt;br /&gt;
		_normals[i] = normal.x;&lt;br /&gt;
		_normals[i+1] = normal.y;&lt;br /&gt;
		_normals[i+2] = normal.z;&lt;br /&gt;
	}&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void DynamicGrid::generateTexCoords()&lt;br /&gt;
{&lt;br /&gt;
	_texCoords = new float[_numVertices * 2];&lt;br /&gt;
	int counter = 0;&lt;br /&gt;
	int line = 0;&lt;br /&gt;
	for (int i=0; i&amp;lt;_numVertices*2; i+=2) {&lt;br /&gt;
		if ( line % 2 == 0) {&lt;br /&gt;
			if (counter %2 == 0) {&lt;br /&gt;
				_texCoords[i] = 0.0f;&lt;br /&gt;
				_texCoords[i+1] = 0.0f;&lt;br /&gt;
			}&lt;br /&gt;
			else {&lt;br /&gt;
				_texCoords[i] = 0.0f;&lt;br /&gt;
				_texCoords[i+1] = 1.0f;&lt;br /&gt;
			}&lt;br /&gt;
		}&lt;br /&gt;
		else {&lt;br /&gt;
			if (counter % 2 == 0) {&lt;br /&gt;
				_texCoords[i] = 1.0f;&lt;br /&gt;
				_texCoords[i+1] = 0.0f;&lt;br /&gt;
			}&lt;br /&gt;
			else {&lt;br /&gt;
				_texCoords[i] = 1.0f;&lt;br /&gt;
				_texCoords[i+1] = 1.0f;&lt;br /&gt;
			}&lt;br /&gt;
		}&lt;br /&gt;
		++counter;&lt;br /&gt;
		if (counter &amp;gt;= _gridSize) {&lt;br /&gt;
			++line;&lt;br /&gt;
			counter = 0;&lt;br /&gt;
		}&lt;br /&gt;
	}&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void DynamicGrid::generateTriangleIndices() &lt;br /&gt;
{&lt;br /&gt;
	_tIndices = new int[ _numTriangleIndices ];&lt;br /&gt;
	int counter = 0;&lt;br /&gt;
	int lineBreakCounter = 0;&lt;br /&gt;
	int counter3 = 0;&lt;br /&gt;
	for (int i=0; i&amp;lt;_numTriangleIndices; i+=3) {&lt;br /&gt;
		if (i%2 ==0) {&lt;br /&gt;
			_tIndices[i] = counter;&lt;br /&gt;
			_tIndices[i+1] = counter+1;&lt;br /&gt;
			_tIndices[i+2] = counter+_gridSize;&lt;br /&gt;
		}&lt;br /&gt;
		else {&lt;br /&gt;
			_tIndices[i] = counter + _gridSize;&lt;br /&gt;
			_tIndices[i+1] = counter + 1;&lt;br /&gt;
			_tIndices[i+2] = counter+_gridSize+1;&lt;br /&gt;
			++counter;&lt;br /&gt;
		}&lt;br /&gt;
		++lineBreakCounter;&lt;br /&gt;
		if (lineBreakCounter == _gridSize*2 - 2) {&lt;br /&gt;
			--counter;&lt;br /&gt;
			++counter3;&lt;br /&gt;
			lineBreakCounter = 0;&lt;br /&gt;
			counter = counter3*_gridSize;&lt;br /&gt;
		}&lt;br /&gt;
		//std::cout&amp;lt;&amp;lt;_tIndices[i]&amp;lt;&amp;lt;&amp;quot;/&amp;quot;&amp;lt;&amp;lt;_tIndices[i+1]&amp;lt;&amp;lt;&amp;quot;/&amp;quot;&amp;lt;&amp;lt;_tIndices[i+2]&amp;lt;&amp;lt;std::endl;&lt;br /&gt;
	}&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void DynamicGrid::update()&lt;br /&gt;
{&lt;br /&gt;
	removeCustomModelNode();&lt;br /&gt;
	delete[] _positions;&lt;br /&gt;
	_positions = 0;&lt;br /&gt;
	delete[] _normals;&lt;br /&gt;
	_normals = 0;&lt;br /&gt;
	generatePositions();&lt;br /&gt;
	generateNormals();&lt;br /&gt;
	addCustomModelNode(-1);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void DynamicGrid::saveGridToFile(std::string fileName_)&lt;br /&gt;
{&lt;br /&gt;
	//std::stringstream fName;&lt;br /&gt;
	//fName&amp;lt;&amp;lt;fileName_;&lt;br /&gt;
	//fName&amp;lt;&amp;lt;&amp;quot;.d2g&amp;quot;;&lt;br /&gt;
	std::stringstream ss;&lt;br /&gt;
	// magic header&lt;br /&gt;
	ss&amp;lt;&amp;lt;&amp;quot;D2SG\n&amp;quot;;&lt;br /&gt;
	// the gridsize (important to know!)&lt;br /&gt;
	ss&amp;lt;&amp;lt;_gridSize;&lt;br /&gt;
	ss&amp;lt;&amp;lt;&amp;quot;\n&amp;quot;;&lt;br /&gt;
	// the quadsize (important to know!)&lt;br /&gt;
	ss&amp;lt;&amp;lt;_size;&lt;br /&gt;
	ss&amp;lt;&amp;lt;&amp;quot;\n&amp;quot;;&lt;br /&gt;
	// number of coordinates (most important to know!)&lt;br /&gt;
	ss&amp;lt;&amp;lt;(_gridSize*_gridSize*3);&lt;br /&gt;
	ss&amp;lt;&amp;lt;&amp;quot;\n&amp;quot;;&lt;br /&gt;
	// coordinates&lt;br /&gt;
	for (int y=0; y&amp;lt;_gridSize; ++y) {&lt;br /&gt;
		for (int x=0; x&amp;lt;_gridSize; ++x) {&lt;br /&gt;
			ss&amp;lt;&amp;lt;_grid[y][x].x;&lt;br /&gt;
			ss&amp;lt;&amp;lt;&amp;quot;\n&amp;quot;;&lt;br /&gt;
			ss&amp;lt;&amp;lt;_grid[y][x].y;&lt;br /&gt;
			ss&amp;lt;&amp;lt;&amp;quot;\n&amp;quot;;&lt;br /&gt;
			ss&amp;lt;&amp;lt;_grid[y][x].z;&lt;br /&gt;
			ss&amp;lt;&amp;lt;&amp;quot;\n&amp;quot;;&lt;br /&gt;
		}&lt;br /&gt;
	}&lt;br /&gt;
	ss&amp;lt;&amp;lt;&amp;quot;\n&amp;quot;;&lt;br /&gt;
	std::ofstream dest(fileName_.c_str());&lt;br /&gt;
	if (dest.is_open()) {&lt;br /&gt;
		dest&amp;lt;&amp;lt;ss.str();&lt;br /&gt;
		dest.close();&lt;br /&gt;
	}&lt;br /&gt;
	std::cout&amp;lt;&amp;lt;&amp;quot;Grid successfully saved to file: &amp;quot;&amp;lt;&amp;lt;fileName_&amp;lt;&amp;lt;std::endl;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
bool DynamicGrid::readGridFromFile(std::string fileName_)&lt;br /&gt;
{&lt;br /&gt;
	int numCoordinates;&lt;br /&gt;
	std::ifstream inFile;&lt;br /&gt;
	inFile.open(fileName_.c_str());&lt;br /&gt;
	bool error = false;&lt;br /&gt;
	if (!inFile) {&lt;br /&gt;
		std::cout&amp;lt;&amp;lt;&amp;quot;Gridfile &amp;quot;&amp;lt;&amp;lt;fileName_&amp;lt;&amp;lt;&amp;quot; could not be found! Creating new grid.&amp;quot;&amp;lt;&amp;lt;std::endl;&lt;br /&gt;
		error = true;&lt;br /&gt;
	}&lt;br /&gt;
	else {&lt;br /&gt;
		std::string line;&lt;br /&gt;
		if (std::getline(inFile, line)) {&lt;br /&gt;
			std::cout&amp;lt;&amp;lt;&amp;quot;Line: &amp;quot;&amp;lt;&amp;lt;line&amp;lt;&amp;lt;std::endl;&lt;br /&gt;
			//if (!(line == &amp;quot;D2SG&amp;quot;)) {&lt;br /&gt;
			if (line.compare(&amp;quot;D2SG&amp;quot;) != 0){&lt;br /&gt;
				std::cout&amp;lt;&amp;lt;&amp;quot;wrong grid-file format &amp;quot;&amp;lt;&amp;lt;line.compare(&amp;quot;D2SG&amp;quot;)&amp;lt;&amp;lt;std::endl;&lt;br /&gt;
				error = true;&lt;br /&gt;
			}&lt;br /&gt;
			else {&lt;br /&gt;
				std::cout&amp;lt;&amp;lt;&amp;quot;Valid grid-file found!&amp;quot;&amp;lt;&amp;lt;std::endl;&lt;br /&gt;
			}&lt;br /&gt;
		}&lt;br /&gt;
		if (std::getline(inFile, line)) {&lt;br /&gt;
			_gridSize = stringToInt(line);&lt;br /&gt;
			//std::cout&amp;lt;&amp;lt;&amp;quot;gridsize: &amp;quot;&amp;lt;&amp;lt;_gridSize&amp;lt;&amp;lt;std::endl;&lt;br /&gt;
		}&lt;br /&gt;
		else {&lt;br /&gt;
			error = true;&lt;br /&gt;
		}&lt;br /&gt;
		if (std::getline(inFile, line)) {&lt;br /&gt;
			_size = stringToInt(line);&lt;br /&gt;
			//std::cout&amp;lt;&amp;lt;&amp;quot;quadsize: &amp;quot;&amp;lt;&amp;lt;_size&amp;lt;&amp;lt;std::endl;&lt;br /&gt;
		}&lt;br /&gt;
		else {&lt;br /&gt;
			error = true;&lt;br /&gt;
		}&lt;br /&gt;
		if (std::getline(inFile, line)) {&lt;br /&gt;
			numCoordinates = stringToInt(line);&lt;br /&gt;
			//std::cout&amp;lt;&amp;lt;&amp;quot;numCoords: &amp;quot;&amp;lt;&amp;lt;numCoordinates&amp;lt;&amp;lt;std::endl;&lt;br /&gt;
		}&lt;br /&gt;
		else {&lt;br /&gt;
			error = true;&lt;br /&gt;
		}&lt;br /&gt;
		if (!error) {&lt;br /&gt;
			_grid = new Vec3f*[_gridSize];&lt;br /&gt;
			for(int y=0; y&amp;lt;_gridSize; ++y) {&lt;br /&gt;
				_grid[y] = new Vec3f[_gridSize];&lt;br /&gt;
				for (int x=0; x&amp;lt;_gridSize; ++x) {&lt;br /&gt;
					Vec3f v;&lt;br /&gt;
					if (std::getline(inFile, line)) {&lt;br /&gt;
						v.x = stringToFloat(line);&lt;br /&gt;
					}&lt;br /&gt;
					if (std::getline(inFile, line)) {&lt;br /&gt;
						v.y = stringToFloat(line);&lt;br /&gt;
					}&lt;br /&gt;
					if (std::getline(inFile, line)) {&lt;br /&gt;
						v.z = stringToFloat(line);&lt;br /&gt;
					}&lt;br /&gt;
					_grid[y][x] = v;&lt;br /&gt;
				}&lt;br /&gt;
			}&lt;br /&gt;
		}&lt;br /&gt;
	}&lt;br /&gt;
	inFile.close();&lt;br /&gt;
	if (error) {&lt;br /&gt;
		_gridSize = GRIDSIZE;&lt;br /&gt;
		_size = 12;&lt;br /&gt;
		_grid = 0;&lt;br /&gt;
	}&lt;br /&gt;
	_numVertices = (_gridSize*_gridSize);&lt;br /&gt;
	_numTriangles = ((_gridSize - 1) * (_gridSize - 1)) * 2;&lt;br /&gt;
	_numTriangleIndices = _numTriangles * 3;&lt;br /&gt;
	_origin = Vec3f(-_size/2*_gridSize, 0, _size/2*_gridSize);&lt;br /&gt;
	return true;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
=Usage example=&lt;/div&gt;</summary>
		<author><name>Wakko</name></author>	</entry>

	<entry>
		<id>http://horde3d.org/wiki/index.php?title=Procedurally_generated_geometry_tutorial&amp;diff=566</id>
		<title>Procedurally generated geometry tutorial</title>
		<link rel="alternate" type="text/html" href="http://horde3d.org/wiki/index.php?title=Procedurally_generated_geometry_tutorial&amp;diff=566"/>
				<updated>2009-10-26T11:37:12Z</updated>
		
		<summary type="html">&lt;p&gt;Wakko: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;'''Work in progress   - Due to the current changes in the Horde API this tutorial will be delayed '''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
= Important notes=&lt;br /&gt;
* The code used here has been tested with Horde3D 1.0.0 beta2 and beta3 and will '''NOT''' work with the latest release (beta4)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=Overview=&lt;br /&gt;
==Basic approach==&lt;br /&gt;
To create and display a procedurally generated mesh that, instead of being loaded from a Horde3D Scene node and a geoemtry file(*.scene.xml, *.geo), will be created in-memory by some algorithm, you have to create a mesh first and then &amp;quot;fake&amp;quot; the .geo-file and the scene node itself and pass it to the engine.&lt;br /&gt;
&lt;br /&gt;
To do that you have to create your procedural geometry first. This is easy for simple shapes like single triangles, squares or triangle-strips, but will become way more difficult when we try to generate complex meshes, e.g. when we have a cloud of points in 3D space and have to describe which points make triangles, and which don't (calculating the triangle indices, texture coordinates and normals).&lt;br /&gt;
&lt;br /&gt;
When we have calculated the geometry itself we need to create a char-stream to make Horde believe the geometry has been read from a file and pass it to Horde as a geometry Resource.&lt;br /&gt;
The final step is to create a Horde3D Scene Node from our procedurally generated mesh and render it into our scene.&lt;br /&gt;
[http://musicracer.de/images/Screenshot-1_small.jpg &lt;br /&gt;
This is how it could look like]&lt;br /&gt;
&lt;br /&gt;
=StreamGenerator=&lt;br /&gt;
&lt;br /&gt;
These classes are only for creating the character stream that will contain the geometry resource.&lt;br /&gt;
&lt;br /&gt;
{{CppSourceCode|&lt;br /&gt;
description= StreamGenerator.h| &lt;br /&gt;
code=&lt;br /&gt;
&amp;lt;source lang=&amp;quot;cpp&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
#pragma once&lt;br /&gt;
#include &amp;lt;sstream&amp;gt;&lt;br /&gt;
#include &amp;lt;string&amp;gt;&lt;br /&gt;
#include &amp;lt;iostream&amp;gt;&lt;br /&gt;
&lt;br /&gt;
class StreamGenerator &lt;br /&gt;
{&lt;br /&gt;
public:&lt;br /&gt;
	StreamGenerator();&lt;br /&gt;
	virtual ~StreamGenerator();&lt;br /&gt;
	virtual const char* getStream() = 0;&lt;br /&gt;
	virtual const int getStreamSize() = 0;&lt;br /&gt;
};&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{CppSourceCode|&lt;br /&gt;
description= StreamGenerator.cpp| &lt;br /&gt;
code=&lt;br /&gt;
&amp;lt;source lang=&amp;quot;cpp&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;quot;StreamGenerator.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
StreamGenerator::StreamGenerator() &lt;br /&gt;
{&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
StreamGenerator::~StreamGenerator()&lt;br /&gt;
{&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{CppSourceCode|&lt;br /&gt;
description= GeometryStreamGenerator.h| &lt;br /&gt;
code=&lt;br /&gt;
&amp;lt;source lang=&amp;quot;cpp&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
#pragma once&lt;br /&gt;
#include &amp;quot;StreamGenerator.h&amp;quot;&lt;br /&gt;
#include &amp;quot;CustomGeometry.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
class GeometryStreamGenerator : public StreamGenerator&lt;br /&gt;
{&lt;br /&gt;
private:&lt;br /&gt;
	std::stringstream* ss;&lt;br /&gt;
	void generate();&lt;br /&gt;
	int numVertices, numTriangleIndices;&lt;br /&gt;
	char* _stream;&lt;br /&gt;
	CustomGeometry* _geom;&lt;br /&gt;
&lt;br /&gt;
public:&lt;br /&gt;
	GeometryStreamGenerator(CustomGeometry* geom_);&lt;br /&gt;
	~GeometryStreamGenerator();&lt;br /&gt;
	const char* getStream();&lt;br /&gt;
	const std::stringstream* getStringStream() { return ss; };&lt;br /&gt;
	const int getStreamSize();&lt;br /&gt;
	const int getNumVertices();&lt;br /&gt;
	const int getNumTriangleIndices();&lt;br /&gt;
	void release();&lt;br /&gt;
};&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{CppSourceCode|&lt;br /&gt;
description= GeometryStreamGenerator.cpp| &lt;br /&gt;
code=&lt;br /&gt;
&amp;lt;source lang=&amp;quot;cpp&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;quot;GeometryStreamGenerator.h&amp;quot;&lt;br /&gt;
#include &amp;quot;time.h&amp;quot;&lt;br /&gt;
#include &amp;quot;utMath.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
GeometryStreamGenerator::GeometryStreamGenerator(CustomGeometry* geom_) : _geom(geom_)&lt;br /&gt;
{&lt;br /&gt;
	ss = new std::stringstream();&lt;br /&gt;
	generate();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
GeometryStreamGenerator::~GeometryStreamGenerator()&lt;br /&gt;
{&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void GeometryStreamGenerator::generate()&lt;br /&gt;
{&lt;br /&gt;
	numVertices = _geom-&amp;gt;getNumVertices();&lt;br /&gt;
	numTriangleIndices = _geom-&amp;gt;getNumTriangleIndices();&lt;br /&gt;
	const std::string _magicHeader = &amp;quot;H3DG&amp;quot;;&lt;br /&gt;
	const int _version = 5;&lt;br /&gt;
	const int _numJoints = 1;&lt;br /&gt;
	const float _identityMatrix[] = {	1.0f, 0.0f, 0.0f, 0.0f,  &lt;br /&gt;
						0.0f, 1.0f, 0.0f, 0.0f,  &lt;br /&gt;
						0.0f, 0.0f, 1.0f, 0.0f,  &lt;br /&gt;
						0.0f, 0.0f, 0.0f, 1.0f};&lt;br /&gt;
	const int _numVertexStreams = 3;&lt;br /&gt;
	const int _magicVertices = 0;&lt;br /&gt;
	const int _vertexStreamElementSize = 12;&lt;br /&gt;
	const float* _positions = _geom-&amp;gt;getPositions();&lt;br /&gt;
	const int _magicNormals = 1;&lt;br /&gt;
	const int _normalsStreamElementSize = 6;&lt;br /&gt;
	const float* _normals = _geom-&amp;gt;getNormals();&lt;br /&gt;
	const int _magicTextureCoords1 = 6;&lt;br /&gt;
	const int _texCoordStreamElementSize = 8;&lt;br /&gt;
	const float* _texCoords = _geom-&amp;gt;getTexCoords();&lt;br /&gt;
	const int* _triangleIndices = _geom-&amp;gt;getTriangleIndices();&lt;br /&gt;
	const int _numMorphTragets = 0;&lt;br /&gt;
	// header&lt;br /&gt;
	ss-&amp;gt;write(_magicHeader.c_str(), 4*sizeof(char));&lt;br /&gt;
	ss-&amp;gt;write((char*)&amp;amp;_version, sizeof(int));&lt;br /&gt;
	// joints (mandatory)&lt;br /&gt;
	ss-&amp;gt;write((char*)&amp;amp;_numJoints, sizeof(int));&lt;br /&gt;
	for (int i=0; i&amp;lt;16; ++i) {&lt;br /&gt;
		ss-&amp;gt;write((char*)&amp;amp;_identityMatrix[i], sizeof(float));&lt;br /&gt;
	}&lt;br /&gt;
	// vertices&lt;br /&gt;
	ss-&amp;gt;write((char*)&amp;amp;_numVertexStreams, sizeof(int));&lt;br /&gt;
	const int numVerts = _geom-&amp;gt;getNumVertices();&lt;br /&gt;
	ss-&amp;gt;write((char*)&amp;amp;numVerts, sizeof(int));&lt;br /&gt;
	ss-&amp;gt;write((char*)&amp;amp;_magicVertices, sizeof(int));&lt;br /&gt;
	ss-&amp;gt;write((char*)&amp;amp;_vertexStreamElementSize, sizeof(int));&lt;br /&gt;
	for (int i=0; i&amp;lt;_geom-&amp;gt;getNumVertices()*3; ++i) {&lt;br /&gt;
		ss-&amp;gt;write((char*)&amp;amp;_positions[i], sizeof(float));&lt;br /&gt;
	}&lt;br /&gt;
	// normals&lt;br /&gt;
	ss-&amp;gt;write((char*)&amp;amp;_magicNormals, sizeof(int));&lt;br /&gt;
	ss-&amp;gt;write((char*)&amp;amp;_normalsStreamElementSize, sizeof(int));&lt;br /&gt;
	for (int i=0; i&amp;lt;_geom-&amp;gt;getNumVertices()*3; ++i) {&lt;br /&gt;
		// do not forget to mutliply the value with 32767 and &lt;br /&gt;
		// then convert it to short before writing to the stream&lt;br /&gt;
		const short f = (short)(_normals[i]*32767);&lt;br /&gt;
		ss-&amp;gt;write((char*)&amp;amp;f, sizeof(short));&lt;br /&gt;
	}&lt;br /&gt;
	// texture coordinates&lt;br /&gt;
	ss-&amp;gt;write((char*)&amp;amp;_magicTextureCoords1, sizeof(int));&lt;br /&gt;
	ss-&amp;gt;write((char*)&amp;amp;_texCoordStreamElementSize, sizeof(int));&lt;br /&gt;
	for (int i=0; i&amp;lt;_geom-&amp;gt;getNumVertices()*2; ++i) {&lt;br /&gt;
		ss-&amp;gt;write((char*)&amp;amp;_texCoords[i], sizeof(float));&lt;br /&gt;
	}&lt;br /&gt;
	// triangle indices&lt;br /&gt;
	const int numTriangleIndices = _geom-&amp;gt;getNumTriangleIndices();&lt;br /&gt;
	ss-&amp;gt;write((char*)&amp;amp;numTriangleIndices, sizeof(int));&lt;br /&gt;
	for (int i=0; i&amp;lt;_geom-&amp;gt;getNumTriangleIndices(); ++i) {&lt;br /&gt;
		ss-&amp;gt;write((char*)&amp;amp;_triangleIndices[i], sizeof(int));&lt;br /&gt;
	}&lt;br /&gt;
	ss-&amp;gt;write((char*)&amp;amp;_numMorphTragets, sizeof(int));&lt;br /&gt;
	_stream = new char[ss-&amp;gt;tellp()];&lt;br /&gt;
	ss-&amp;gt;read(_stream, ss-&amp;gt;tellp());&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
const char* GeometryStreamGenerator::getStream()&lt;br /&gt;
{&lt;br /&gt;
	return _stream;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
const int GeometryStreamGenerator::getStreamSize() &lt;br /&gt;
{&lt;br /&gt;
	int t = (int)ss-&amp;gt;tellp();&lt;br /&gt;
	return t;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
const int GeometryStreamGenerator::getNumVertices()&lt;br /&gt;
{&lt;br /&gt;
	return numVertices;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
const int GeometryStreamGenerator::getNumTriangleIndices()&lt;br /&gt;
{&lt;br /&gt;
	return numTriangleIndices;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void GeometryStreamGenerator::release()&lt;br /&gt;
{&lt;br /&gt;
	ss-&amp;gt;flush();&lt;br /&gt;
	ss-&amp;gt;clear();&lt;br /&gt;
	delete ss;&lt;br /&gt;
	ss = 0;&lt;br /&gt;
	delete[] _stream;&lt;br /&gt;
	_stream = 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
=CustomGeometry base class=&lt;br /&gt;
&lt;br /&gt;
Base class for the custom geometry. This class currently contains lots of deprecated stuff, e.g. the update() function. This function was used to update an in-memory gemoetry resource in the &amp;quot;punk-rock&amp;quot;-way. Until Horde3D Beta3 the geometry resources were read-only, so directmanipulation of vertices was impossible. To modify the vertices I had to unload the geometry resource, re-create it with the new vertex-positions and load it into Horde again. '''This is not necessary any more because since Beta4 the geometry resources are not read-only anymore.'''&lt;br /&gt;
&lt;br /&gt;
All custom geometry classes should be derived from this class and implement the abstract functions as needed. (See the examples below)&lt;br /&gt;
&lt;br /&gt;
{{CppSourceCode|&lt;br /&gt;
description= CustomGeometry.h| &lt;br /&gt;
code=&lt;br /&gt;
&amp;lt;source lang=&amp;quot;cpp&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
#pragma once&lt;br /&gt;
/**&lt;br /&gt;
 * Abstract class for custom/dynamic geometry&lt;br /&gt;
 **/&lt;br /&gt;
#include &amp;quot;utMath.h&amp;quot;&lt;br /&gt;
#include &amp;quot;Horde3D.h&amp;quot;&lt;br /&gt;
#include &amp;lt;string&amp;gt;&lt;br /&gt;
&lt;br /&gt;
class CustomGeometry &lt;br /&gt;
{&lt;br /&gt;
protected:&lt;br /&gt;
	float _size;&lt;br /&gt;
	Vec3f _origin;&lt;br /&gt;
	int _numVertices;&lt;br /&gt;
	int _numTriangles;&lt;br /&gt;
	int _numTriangleIndices;&lt;br /&gt;
	float* _positions;&lt;br /&gt;
	float* _normals;&lt;br /&gt;
	float* _texCoords;&lt;br /&gt;
	int* _tIndices;&lt;br /&gt;
	std::string _name;&lt;br /&gt;
	NodeHandle _model;&lt;br /&gt;
	NodeHandle _parent;&lt;br /&gt;
	ResHandle _material;&lt;br /&gt;
	virtual void generatePositions() = 0;&lt;br /&gt;
	virtual void generateNormals() = 0;&lt;br /&gt;
	virtual void generateTexCoords() = 0;&lt;br /&gt;
	virtual void generateTriangleIndices() = 0;&lt;br /&gt;
&lt;br /&gt;
public:&lt;br /&gt;
	CustomGeometry();&lt;br /&gt;
	virtual void generate() = 0;&lt;br /&gt;
	const int getNumVertices() { return _numVertices; }&lt;br /&gt;
	const float* getPositions() { return _positions; }&lt;br /&gt;
	const float* getNormals() { return _normals; }&lt;br /&gt;
	const float* getTexCoords() { return _texCoords; }&lt;br /&gt;
	const int* getTriangleIndices() { return _tIndices; }&lt;br /&gt;
	const int getNumTriangles() { return _numTriangles; }&lt;br /&gt;
	const int getNumTriangleIndices() { return _numTriangleIndices; }&lt;br /&gt;
	void release();&lt;br /&gt;
	const Vec3f getInterpolatedNormal(Vec3f n1_, Vec3f n2_);&lt;br /&gt;
	// pass -1 as the parameter to leave the parent node unchanged&lt;br /&gt;
	void addCustomModelNode(NodeHandle parent_);&lt;br /&gt;
	bool removeCustomModelNode();&lt;br /&gt;
	void setMaterial(ResHandle material_) { _material = material_; }&lt;br /&gt;
	void setParent(NodeHandle parent_) { _parent = parent_; }&lt;br /&gt;
	NodeHandle getModel() { return _model; }&lt;br /&gt;
	ResHandle getMaterial() { return _material; }&lt;br /&gt;
	void update();&lt;br /&gt;
	Vec3f getOrigin() { return _origin; }&lt;br /&gt;
	void setOrigin(Vec3f origin_) { _origin = origin_; }&lt;br /&gt;
	const float getSize() { return _size; }&lt;br /&gt;
};&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{CppSourceCode|&lt;br /&gt;
description= CustomGeometry.cpp| &lt;br /&gt;
code=&lt;br /&gt;
&amp;lt;source lang=&amp;quot;cpp&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;quot;CustomGeometry.h&amp;quot;&lt;br /&gt;
#include &amp;lt;iostream&amp;gt;&lt;br /&gt;
#include &amp;lt;string&amp;gt;&lt;br /&gt;
#include &amp;lt;sstream&amp;gt;&lt;br /&gt;
#include &amp;lt;fstream&amp;gt;&lt;br /&gt;
#include &amp;quot;GeometryStreamGenerator.h&amp;quot;&lt;br /&gt;
#include &amp;quot;Horde3DUtils.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
CustomGeometry::CustomGeometry() : _name(&amp;quot;default&amp;quot;), _size(1)&lt;br /&gt;
{&lt;br /&gt;
	_origin = Vec3f(0, 0, 0);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void CustomGeometry::release()&lt;br /&gt;
{&lt;br /&gt;
	delete[] _positions;&lt;br /&gt;
	_positions = 0;&lt;br /&gt;
	delete[] _normals;&lt;br /&gt;
	_normals = 0;&lt;br /&gt;
	delete[] _texCoords;&lt;br /&gt;
	_texCoords = 0;&lt;br /&gt;
	delete[] _tIndices;&lt;br /&gt;
	_tIndices = 0;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
const Vec3f CustomGeometry::getInterpolatedNormal(Vec3f n1_, Vec3f n2_) &lt;br /&gt;
{&lt;br /&gt;
	Vec3f newNormal = n1_ + n2_;&lt;br /&gt;
	float length = newNormal.length();&lt;br /&gt;
	return newNormal/length;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void CustomGeometry::addCustomModelNode(NodeHandle parent_)&lt;br /&gt;
{&lt;br /&gt;
	//std::stringstream* sa = new std::stringstream();&lt;br /&gt;
	std::stringstream ss;&lt;br /&gt;
	if (parent_ != -1) &lt;br /&gt;
		_parent = parent_;&lt;br /&gt;
	ss&amp;lt;&amp;lt; &amp;quot;customGeometry-&amp;quot;;&lt;br /&gt;
	ss&amp;lt;&amp;lt;_name;&lt;br /&gt;
	GeometryStreamGenerator* gsg = new GeometryStreamGenerator(this);&lt;br /&gt;
	ResHandle customGeoRes = Horde3D::addResource(ResourceTypes::Geometry, ss.str().c_str(), 0);&lt;br /&gt;
	Horde3D::loadResource(customGeoRes, gsg-&amp;gt;getStream(), gsg-&amp;gt;getStreamSize());&lt;br /&gt;
	// model_node_name&lt;br /&gt;
	ss&amp;lt;&amp;lt;&amp;quot;-Node&amp;quot;;&lt;br /&gt;
	_model = Horde3D::addModelNode(_parent, ss.str().c_str(), customGeoRes);&lt;br /&gt;
	// mesh_name&lt;br /&gt;
	ss&amp;lt;&amp;lt;&amp;quot;-Mesh&amp;quot;;&lt;br /&gt;
	Horde3D::addMeshNode(_model, ss.str().c_str(), _material, 0, gsg-&amp;gt;getNumTriangleIndices(), 0, gsg-&amp;gt;getNumVertices()-1);&lt;br /&gt;
	Horde3DUtils::dumpMessages();&lt;br /&gt;
	ss.str(&amp;quot;&amp;quot;);&lt;br /&gt;
	ss.clear();&lt;br /&gt;
	ss.flush();&lt;br /&gt;
	gsg-&amp;gt;release();&lt;br /&gt;
	delete gsg;&lt;br /&gt;
	gsg = 0;&lt;br /&gt;
	//Horde3D::setNodeTransform(_model, _origin.x, _origin.y, _origin.z, 0, 0, 0, 1, 1, 1);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
bool CustomGeometry::removeCustomModelNode()&lt;br /&gt;
{&lt;br /&gt;
	std::stringstream* ss = new std::stringstream();&lt;br /&gt;
	*ss&amp;lt;&amp;lt; &amp;quot;customGeometry-&amp;quot;;&lt;br /&gt;
	*ss&amp;lt;&amp;lt;_name;&lt;br /&gt;
	ResHandle rh = Horde3D::findResource(ResourceTypes::Geometry, ss-&amp;gt;str().c_str());&lt;br /&gt;
	if (Horde3D::isResourceLoaded(rh)) {&lt;br /&gt;
		Horde3D::removeResource(rh);&lt;br /&gt;
		Horde3D::unloadResource(rh);&lt;br /&gt;
		Horde3D::removeNode(_model);&lt;br /&gt;
		Horde3D::releaseUnusedResources();&lt;br /&gt;
		Horde3DUtils::dumpMessages();&lt;br /&gt;
		delete ss;&lt;br /&gt;
		return true;&lt;br /&gt;
	}&lt;br /&gt;
	else &lt;br /&gt;
		return false;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void CustomGeometry::update()&lt;br /&gt;
{&lt;br /&gt;
	removeCustomModelNode();&lt;br /&gt;
	addCustomModelNode(-1);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
=Simple Square=&lt;br /&gt;
&lt;br /&gt;
A simple two-sided (hard-coded) square. This is pretty straight forward and demonstrates how to derive from the CustomGeometry class and how the triangle indices work.&lt;br /&gt;
&lt;br /&gt;
{{CppSourceCode|&lt;br /&gt;
description= DynamicSquare.h| &lt;br /&gt;
code=&lt;br /&gt;
&amp;lt;source lang=&amp;quot;cpp&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
/**&lt;br /&gt;
 * Class representing a square &lt;br /&gt;
 **/&lt;br /&gt;
#pragma once&lt;br /&gt;
#include &amp;quot;CustomGeometry.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
class DynamicSquare : public CustomGeometry&lt;br /&gt;
{&lt;br /&gt;
protected:&lt;br /&gt;
	virtual void generatePositions();&lt;br /&gt;
	virtual void generateNormals();&lt;br /&gt;
	virtual void generateTexCoords();&lt;br /&gt;
	virtual void generateTriangleIndices();&lt;br /&gt;
&lt;br /&gt;
public:&lt;br /&gt;
	DynamicSquare();&lt;br /&gt;
	virtual void generate();&lt;br /&gt;
	DynamicSquare(const float size_, const std::string name_);&lt;br /&gt;
};&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{CppSourceCode|&lt;br /&gt;
description= DynamicSquare.cpp| &lt;br /&gt;
code=&lt;br /&gt;
&amp;lt;source lang=&amp;quot;cpp&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;quot;DynamicSquare.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
DynamicSquare::DynamicSquare() : CustomGeometry()&lt;br /&gt;
{&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
DynamicSquare::DynamicSquare(const float size_, const std::string name_) &lt;br /&gt;
{&lt;br /&gt;
	_size = size_;&lt;br /&gt;
	_name = name_;&lt;br /&gt;
	_numVertices = 8;&lt;br /&gt;
	_numTriangles = 4;&lt;br /&gt;
	_numTriangleIndices = (_numVertices - 2) * 3;&lt;br /&gt;
	//generate();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void DynamicSquare::generate() &lt;br /&gt;
{&lt;br /&gt;
	generatePositions();&lt;br /&gt;
	generateNormals();&lt;br /&gt;
	generateTexCoords();&lt;br /&gt;
	generateTriangleIndices();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void DynamicSquare::generatePositions() &lt;br /&gt;
{&lt;br /&gt;
	_positions = new float[_numVertices * 3 * 2];&lt;br /&gt;
	// front left point (x/y/z)&lt;br /&gt;
	_positions[0] = _origin.x * _size - _size/2;&lt;br /&gt;
	_positions[1] = _origin.y;&lt;br /&gt;
	_positions[2] = _origin.z * _size -_size/2;&lt;br /&gt;
	// front right point (x/y/z)&lt;br /&gt;
	_positions[3] = _origin.x * _size + _size/2;&lt;br /&gt;
	_positions[4] = _origin.y;&lt;br /&gt;
	_positions[5] = _origin.z * _size - _size/2;&lt;br /&gt;
	// back left point (x/y/z)&lt;br /&gt;
	_positions[6] = _origin.x * _size - _size/2;&lt;br /&gt;
	_positions[7] = _origin.y;&lt;br /&gt;
	_positions[8] = _origin.z * _size + _size/2;&lt;br /&gt;
	// back right point (x/y/z)&lt;br /&gt;
	_positions[9] = _origin.x * _size + _size/2;&lt;br /&gt;
	_positions[10] = _origin.y;&lt;br /&gt;
	_positions[11] = _origin.z * _size + _size/2;&lt;br /&gt;
&lt;br /&gt;
        // comment the bottom side if you do not want to have a two-sided sq&lt;br /&gt;
	// bottom sideuare&lt;br /&gt;
	// front left point (x/y/z)&lt;br /&gt;
	_positions[12] = _origin.x * _size - _size/2;&lt;br /&gt;
	_positions[13] = _origin.y-0.5;&lt;br /&gt;
	_positions[14] = _origin.z * _size - _size/2;&lt;br /&gt;
	// front right point (x/y/z)&lt;br /&gt;
	_positions[15] = _origin.x * _size + _size/2;&lt;br /&gt;
	_positions[16] = _origin.y-0.5;&lt;br /&gt;
	_positions[17] = _origin.z * _size - _size/2;&lt;br /&gt;
	// back left point (x/y/z)&lt;br /&gt;
	_positions[18] = _origin.x * _size - _size/2;&lt;br /&gt;
	_positions[19] = _origin.y-0.5;&lt;br /&gt;
	_positions[20] = _origin.z * _size + _size/2;&lt;br /&gt;
	// back right point (x/y/z)&lt;br /&gt;
	_positions[21] = _origin.x * _size + _size/2;&lt;br /&gt;
	_positions[22] = _origin.y-0.5;&lt;br /&gt;
	_positions[23] = _origin.z * _size + _size/2;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void DynamicSquare::generateNormals() &lt;br /&gt;
{&lt;br /&gt;
	_normals = new float[_numVertices * 3*2];&lt;br /&gt;
	for (int i=0; i&amp;lt; 12; i+=3) {&lt;br /&gt;
		_normals[i] = 0;&lt;br /&gt;
		_normals[i+1] = 1;&lt;br /&gt;
		_normals[i+2] = 0;&lt;br /&gt;
	}&lt;br /&gt;
	for (int i=13; i&amp;lt; 24; i+=3) {&lt;br /&gt;
		_normals[i] = 0;&lt;br /&gt;
		_normals[i+1] = -1;&lt;br /&gt;
		_normals[i+2] = 0;&lt;br /&gt;
	}&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void DynamicSquare::generateTexCoords()&lt;br /&gt;
{&lt;br /&gt;
	_texCoords = new float[_numVertices * 2 * 2];&lt;br /&gt;
	_texCoords[0] = 0.0f; &lt;br /&gt;
	_texCoords[1] = 0.0f;&lt;br /&gt;
	_texCoords[2] = 1.0f; &lt;br /&gt;
	_texCoords[3] = 0.0f;&lt;br /&gt;
	_texCoords[4] = 0.0f; &lt;br /&gt;
	_texCoords[5] = 1.0f;&lt;br /&gt;
	_texCoords[6] = 1.0f; &lt;br /&gt;
	_texCoords[7] = 1.0f;&lt;br /&gt;
	_texCoords[8] = 0.0f; &lt;br /&gt;
	_texCoords[9] = 0.0f;&lt;br /&gt;
	_texCoords[10] = 1.0f; &lt;br /&gt;
	_texCoords[11] = 0.0f;&lt;br /&gt;
	_texCoords[12] = 0.0f; &lt;br /&gt;
	_texCoords[13] = 1.0f;&lt;br /&gt;
	_texCoords[14] = 1.0f; &lt;br /&gt;
	_texCoords[15] = 1.0f;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void DynamicSquare::generateTriangleIndices() &lt;br /&gt;
{&lt;br /&gt;
	_tIndices = new int[_numTriangleIndices ];&lt;br /&gt;
	_tIndices[0] = 0;&lt;br /&gt;
	_tIndices[1] = 2;&lt;br /&gt;
	_tIndices[2] = 1;&lt;br /&gt;
	_tIndices[3] = 1;&lt;br /&gt;
	_tIndices[4] = 2;&lt;br /&gt;
	_tIndices[5] = 3;&lt;br /&gt;
	_tIndices[6] = 5;&lt;br /&gt;
	_tIndices[7] = 7;&lt;br /&gt;
	_tIndices[8] = 6;&lt;br /&gt;
	_tIndices[9] = 6;&lt;br /&gt;
	_tIndices[10] = 4;&lt;br /&gt;
	_tIndices[11] = 5;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
=Simple Grid=&lt;br /&gt;
&lt;br /&gt;
All the work above was made to create my own interactive terrain generator(screenshot on top of this page) for a A* pathfinding demonstrator. The Grid-class actually generates a grid of points and allows to extrude each point and re-generate the mesh in realtime by overriding the CustomGeometry function &amp;quot;update()&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
[http://musicracer.de/images/grid_01_english.png&lt;br /&gt;
This is how it looks internally]&lt;br /&gt;
{{CppSourceCode|&lt;br /&gt;
description= DynamicGrid.h| &lt;br /&gt;
code=&lt;br /&gt;
&amp;lt;source lang=&amp;quot;cpp&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
/**&lt;br /&gt;
&lt;br /&gt;
 * Class representing a square &lt;br /&gt;
&lt;br /&gt;
 **/&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
#pragma once&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
#include &amp;quot;CustomGeometry.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
class DynamicGrid : public CustomGeometry&lt;br /&gt;
&lt;br /&gt;
{&lt;br /&gt;
&lt;br /&gt;
protected:&lt;br /&gt;
&lt;br /&gt;
	virtual void generatePositions();&lt;br /&gt;
&lt;br /&gt;
	virtual void generateNormals();&lt;br /&gt;
&lt;br /&gt;
	virtual void generateTexCoords();&lt;br /&gt;
&lt;br /&gt;
	virtual void generateTriangleIndices();&lt;br /&gt;
&lt;br /&gt;
	void generateGrid();&lt;br /&gt;
&lt;br /&gt;
	int _gridSize;&lt;br /&gt;
&lt;br /&gt;
	Vec3f** _grid;&lt;br /&gt;
&lt;br /&gt;
	std::string _fileName;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
public:&lt;br /&gt;
&lt;br /&gt;
	DynamicGrid();&lt;br /&gt;
&lt;br /&gt;
	virtual void generate();&lt;br /&gt;
&lt;br /&gt;
	DynamicGrid(const float size_, const std::string name_, std::string fileName_);&lt;br /&gt;
&lt;br /&gt;
	Vec3f getPointAt(int x_, int y_) { return _grid[y_][x_]; }&lt;br /&gt;
&lt;br /&gt;
	void setPointAt(int x_, int y_, Vec3f newPos_) { _grid[y_][x_] = newPos_; }&lt;br /&gt;
&lt;br /&gt;
	int getGridSize() { return _gridSize; }&lt;br /&gt;
&lt;br /&gt;
	// overwrite update() from parent class&lt;br /&gt;
&lt;br /&gt;
	void update();&lt;br /&gt;
&lt;br /&gt;
	void saveGridToFile(std::string fileName_);&lt;br /&gt;
&lt;br /&gt;
	bool readGridFromFile(std::string fileName_);&lt;br /&gt;
&lt;br /&gt;
};&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{CppSourceCode|&lt;br /&gt;
description= DynamicGrid.cpp| &lt;br /&gt;
code=&lt;br /&gt;
&amp;lt;source lang=&amp;quot;cpp&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;quot;DynamicGrid.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
#include &amp;quot;rng.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
#include &amp;lt;iostream&amp;gt;&lt;br /&gt;
&lt;br /&gt;
#include &amp;lt;string&amp;gt;&lt;br /&gt;
&lt;br /&gt;
#include &amp;lt;sstream&amp;gt;&lt;br /&gt;
&lt;br /&gt;
#include &amp;lt;fstream&amp;gt;&lt;br /&gt;
&lt;br /&gt;
#include &amp;quot;util.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
#define GRIDSIZE 50&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
DynamicGrid::DynamicGrid() : CustomGeometry()&lt;br /&gt;
&lt;br /&gt;
{&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
DynamicGrid::DynamicGrid(const float size_, const std::string name_, std::string fileName_) : _fileName(fileName_) &lt;br /&gt;
&lt;br /&gt;
{&lt;br /&gt;
&lt;br /&gt;
	_name = name_;&lt;br /&gt;
&lt;br /&gt;
	_positions = 0;&lt;br /&gt;
&lt;br /&gt;
	_normals = 0;&lt;br /&gt;
&lt;br /&gt;
	_texCoords = 0;&lt;br /&gt;
&lt;br /&gt;
	_tIndices = 0;&lt;br /&gt;
&lt;br /&gt;
	readGridFromFile(_fileName);&lt;br /&gt;
&lt;br /&gt;
	_numVertices = (_gridSize*_gridSize);&lt;br /&gt;
&lt;br /&gt;
	_numTriangles = ((_gridSize - 1) * (_gridSize - 1)) * 2;&lt;br /&gt;
&lt;br /&gt;
	_numTriangleIndices = _numTriangles * 3;&lt;br /&gt;
&lt;br /&gt;
	_origin = Vec3f(-_size/2*_gridSize, 0, _size/2*_gridSize);&lt;br /&gt;
&lt;br /&gt;
	/*&lt;br /&gt;
&lt;br /&gt;
	std::cout&amp;lt;&amp;lt;&amp;quot;numVerts: &amp;quot;&amp;lt;&amp;lt;_numVertices&amp;lt;&amp;lt;std::endl;&lt;br /&gt;
&lt;br /&gt;
	std::cout&amp;lt;&amp;lt;&amp;quot;numTris: &amp;quot;&amp;lt;&amp;lt;_numTriangles&amp;lt;&amp;lt;std::endl;&lt;br /&gt;
&lt;br /&gt;
	std::cout&amp;lt;&amp;lt;&amp;quot;numTInds: &amp;quot;&amp;lt;&amp;lt;_numTriangleIndices&amp;lt;&amp;lt;std::endl;&lt;br /&gt;
&lt;br /&gt;
	std::cout&amp;lt;&amp;lt;&amp;quot;size: &amp;quot;&amp;lt;&amp;lt;_size&amp;lt;&amp;lt;std::endl;&lt;br /&gt;
&lt;br /&gt;
	*/&lt;br /&gt;
&lt;br /&gt;
	//std::cout&amp;lt;&amp;lt;_origin.x&amp;lt;&amp;lt;&amp;quot;/&amp;quot;&amp;lt;&amp;lt;_origin.y&amp;lt;&amp;lt;&amp;quot;/&amp;quot;&amp;lt;&amp;lt;_origin.z&amp;lt;&amp;lt;std::endl;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
	//generate();&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
void DynamicGrid::generate() &lt;br /&gt;
&lt;br /&gt;
{&lt;br /&gt;
&lt;br /&gt;
	if (!_grid)&lt;br /&gt;
&lt;br /&gt;
		generateGrid();&lt;br /&gt;
&lt;br /&gt;
	generatePositions();&lt;br /&gt;
&lt;br /&gt;
	generateNormals();&lt;br /&gt;
&lt;br /&gt;
	generateTexCoords();&lt;br /&gt;
&lt;br /&gt;
	generateTriangleIndices();&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
// the following two functions could be combined into one single loop, but I left it this way for clarity...&lt;br /&gt;
void DynamicGrid::generateGrid()&lt;br /&gt;
&lt;br /&gt;
{&lt;br /&gt;
&lt;br /&gt;
	RNG rng;&lt;br /&gt;
&lt;br /&gt;
	_grid = new Vec3f*[_gridSize];&lt;br /&gt;
&lt;br /&gt;
	for (int y=0; y&amp;lt;_gridSize; ++y) {&lt;br /&gt;
&lt;br /&gt;
		_grid[y] = new Vec3f[_gridSize];&lt;br /&gt;
&lt;br /&gt;
		for (int x=0; x&amp;lt;_gridSize; ++x) {&lt;br /&gt;
&lt;br /&gt;
			long rand = (abs((int)rng.rand_int31()) %3);&lt;br /&gt;
&lt;br /&gt;
			_grid[y][x] = Vec3f(_origin.x/2+_size/2*x, rand, _origin.z/2-_size/2*y);&lt;br /&gt;
&lt;br /&gt;
			//std::cout&amp;lt;&amp;lt;_grid[y][x].x&amp;lt;&amp;lt;&amp;quot;/&amp;quot;&amp;lt;&amp;lt;_grid[y][x].y&amp;lt;&amp;lt;&amp;quot;/&amp;quot;&amp;lt;&amp;lt;_grid[y][x].z&amp;lt;&amp;lt;std::endl;&lt;br /&gt;
&lt;br /&gt;
		}&lt;br /&gt;
&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
void DynamicGrid::generatePositions() &lt;br /&gt;
&lt;br /&gt;
{&lt;br /&gt;
&lt;br /&gt;
	_positions = new float[_numVertices*3];&lt;br /&gt;
&lt;br /&gt;
	int counter = 0;&lt;br /&gt;
&lt;br /&gt;
	for (int i=0; i&amp;lt;_numVertices*3; i+=3) {&lt;br /&gt;
&lt;br /&gt;
		int y = counter / _gridSize;&lt;br /&gt;
&lt;br /&gt;
		int x = counter % _gridSize;&lt;br /&gt;
&lt;br /&gt;
		_positions[i] = _grid[y][x].x;&lt;br /&gt;
&lt;br /&gt;
		_positions[i+1] = _grid[y][x].y;&lt;br /&gt;
&lt;br /&gt;
		_positions[i+2] = _grid[y][x].z;&lt;br /&gt;
&lt;br /&gt;
		++counter;&lt;br /&gt;
&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
void DynamicGrid::generateNormals() &lt;br /&gt;
&lt;br /&gt;
{&lt;br /&gt;
&lt;br /&gt;
	_normals = new float[_numVertices * 3];&lt;br /&gt;
&lt;br /&gt;
	for (int i=0; i&amp;lt; _numVertices*3; i+=3) {&lt;br /&gt;
&lt;br /&gt;
		int pos = i/3;&lt;br /&gt;
&lt;br /&gt;
		int xPos = pos % _gridSize;&lt;br /&gt;
&lt;br /&gt;
		int yPos = pos / _gridSize;&lt;br /&gt;
&lt;br /&gt;
		Vec3f xPred;&lt;br /&gt;
&lt;br /&gt;
		Vec3f xSucc;&lt;br /&gt;
&lt;br /&gt;
		Vec3f yPred;&lt;br /&gt;
&lt;br /&gt;
		Vec3f ySucc;&lt;br /&gt;
&lt;br /&gt;
		Vec3f normal;&lt;br /&gt;
&lt;br /&gt;
		if (xPos &amp;gt; 0 &amp;amp;&amp;amp; yPos &amp;gt; 0) {&lt;br /&gt;
&lt;br /&gt;
			// if the current vertex is inside the grid we will calculate&lt;br /&gt;
&lt;br /&gt;
			// two normals from the previous&amp;amp;next point and our current vertex&lt;br /&gt;
&lt;br /&gt;
			if (xPos &amp;lt; _gridSize-1 &amp;amp;&amp;amp; yPos &amp;lt; _gridSize-1) {&lt;br /&gt;
&lt;br /&gt;
				xSucc = _grid[yPos][xPos+1];&lt;br /&gt;
&lt;br /&gt;
				xPred = _grid[yPos][xPos-1];&lt;br /&gt;
&lt;br /&gt;
				ySucc = _grid[yPos+1][xPos];&lt;br /&gt;
&lt;br /&gt;
				yPred = _grid[yPos-1][xPos];&lt;br /&gt;
&lt;br /&gt;
				Vec3f v1 = xSucc - _grid[yPos][xPos];&lt;br /&gt;
&lt;br /&gt;
				if (v1.y &amp;lt; 0)&lt;br /&gt;
&lt;br /&gt;
					v1.y *= -1;&lt;br /&gt;
&lt;br /&gt;
				Vec3f v2 = xPred - _grid[yPos][xPos];&lt;br /&gt;
&lt;br /&gt;
				if (v2.y &amp;lt; 0)&lt;br /&gt;
&lt;br /&gt;
					v2.y *= -1;&lt;br /&gt;
&lt;br /&gt;
				v1 += v2;&lt;br /&gt;
&lt;br /&gt;
				Vec3f v3 = ySucc - _grid[yPos][xPos];&lt;br /&gt;
&lt;br /&gt;
				if (v3.y &amp;lt; 0)&lt;br /&gt;
&lt;br /&gt;
					v3.y *= -1;&lt;br /&gt;
&lt;br /&gt;
				Vec3f v4 = yPred - _grid[yPos][xPos];&lt;br /&gt;
&lt;br /&gt;
				if (v4.y &amp;lt; 0)&lt;br /&gt;
&lt;br /&gt;
					v4.y *= -1;&lt;br /&gt;
&lt;br /&gt;
				v3 += v4;&lt;br /&gt;
&lt;br /&gt;
				normal = getInterpolatedNormal(v1, v3);&lt;br /&gt;
&lt;br /&gt;
			}&lt;br /&gt;
&lt;br /&gt;
			// if the vertex is on the grid's border the normal will simply be 0/1/0&lt;br /&gt;
&lt;br /&gt;
			else {&lt;br /&gt;
&lt;br /&gt;
				normal = Vec3f(0,1,0);&lt;br /&gt;
&lt;br /&gt;
			}&lt;br /&gt;
&lt;br /&gt;
		}&lt;br /&gt;
&lt;br /&gt;
		else {&lt;br /&gt;
&lt;br /&gt;
			normal = Vec3f(0,1,0);&lt;br /&gt;
&lt;br /&gt;
		}&lt;br /&gt;
&lt;br /&gt;
		_normals[i] = normal.x;&lt;br /&gt;
&lt;br /&gt;
		_normals[i+1] = normal.y;&lt;br /&gt;
&lt;br /&gt;
		_normals[i+2] = normal.z;&lt;br /&gt;
&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
void DynamicGrid::generateTexCoords()&lt;br /&gt;
&lt;br /&gt;
{&lt;br /&gt;
&lt;br /&gt;
	_texCoords = new float[_numVertices * 2];&lt;br /&gt;
&lt;br /&gt;
	int counter = 0;&lt;br /&gt;
&lt;br /&gt;
	int line = 0;&lt;br /&gt;
&lt;br /&gt;
	for (int i=0; i&amp;lt;_numVertices*2; i+=2) {&lt;br /&gt;
&lt;br /&gt;
		if ( line % 2 == 0) {&lt;br /&gt;
&lt;br /&gt;
			if (counter %2 == 0) {&lt;br /&gt;
&lt;br /&gt;
				_texCoords[i] = 0.0f;&lt;br /&gt;
&lt;br /&gt;
				_texCoords[i+1] = 0.0f;&lt;br /&gt;
&lt;br /&gt;
			}&lt;br /&gt;
&lt;br /&gt;
			else {&lt;br /&gt;
&lt;br /&gt;
				_texCoords[i] = 0.0f;&lt;br /&gt;
&lt;br /&gt;
				_texCoords[i+1] = 1.0f;&lt;br /&gt;
&lt;br /&gt;
			}&lt;br /&gt;
&lt;br /&gt;
		}&lt;br /&gt;
&lt;br /&gt;
		else {&lt;br /&gt;
&lt;br /&gt;
			if (counter % 2 == 0) {&lt;br /&gt;
&lt;br /&gt;
				_texCoords[i] = 1.0f;&lt;br /&gt;
&lt;br /&gt;
				_texCoords[i+1] = 0.0f;&lt;br /&gt;
&lt;br /&gt;
			}&lt;br /&gt;
&lt;br /&gt;
			else {&lt;br /&gt;
&lt;br /&gt;
				_texCoords[i] = 1.0f;&lt;br /&gt;
&lt;br /&gt;
				_texCoords[i+1] = 1.0f;&lt;br /&gt;
&lt;br /&gt;
			}&lt;br /&gt;
&lt;br /&gt;
		}&lt;br /&gt;
&lt;br /&gt;
		++counter;&lt;br /&gt;
&lt;br /&gt;
		if (counter &amp;gt;= _gridSize) {&lt;br /&gt;
&lt;br /&gt;
			++line;&lt;br /&gt;
&lt;br /&gt;
			counter = 0;&lt;br /&gt;
&lt;br /&gt;
		}&lt;br /&gt;
&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
void DynamicGrid::generateTriangleIndices() &lt;br /&gt;
&lt;br /&gt;
{&lt;br /&gt;
&lt;br /&gt;
	_tIndices = new int[ _numTriangleIndices ];&lt;br /&gt;
&lt;br /&gt;
	int counter = 0;&lt;br /&gt;
&lt;br /&gt;
	int lineBreakCounter = 0;&lt;br /&gt;
&lt;br /&gt;
	int counter3 = 0;&lt;br /&gt;
&lt;br /&gt;
	for (int i=0; i&amp;lt;_numTriangleIndices; i+=3) {&lt;br /&gt;
&lt;br /&gt;
		if (i%2 ==0) {&lt;br /&gt;
&lt;br /&gt;
			_tIndices[i] = counter;&lt;br /&gt;
&lt;br /&gt;
			_tIndices[i+1] = counter+1;&lt;br /&gt;
&lt;br /&gt;
			_tIndices[i+2] = counter+_gridSize;&lt;br /&gt;
&lt;br /&gt;
		}&lt;br /&gt;
&lt;br /&gt;
		else {&lt;br /&gt;
&lt;br /&gt;
			_tIndices[i] = counter + _gridSize;&lt;br /&gt;
&lt;br /&gt;
			_tIndices[i+1] = counter + 1;&lt;br /&gt;
&lt;br /&gt;
			_tIndices[i+2] = counter+_gridSize+1;&lt;br /&gt;
&lt;br /&gt;
			++counter;&lt;br /&gt;
&lt;br /&gt;
		}&lt;br /&gt;
&lt;br /&gt;
		++lineBreakCounter;&lt;br /&gt;
&lt;br /&gt;
		if (lineBreakCounter == _gridSize*2 - 2) {&lt;br /&gt;
&lt;br /&gt;
			--counter;&lt;br /&gt;
&lt;br /&gt;
			++counter3;&lt;br /&gt;
&lt;br /&gt;
			lineBreakCounter = 0;&lt;br /&gt;
&lt;br /&gt;
			counter = counter3*_gridSize;&lt;br /&gt;
&lt;br /&gt;
		}&lt;br /&gt;
&lt;br /&gt;
		//std::cout&amp;lt;&amp;lt;_tIndices[i]&amp;lt;&amp;lt;&amp;quot;/&amp;quot;&amp;lt;&amp;lt;_tIndices[i+1]&amp;lt;&amp;lt;&amp;quot;/&amp;quot;&amp;lt;&amp;lt;_tIndices[i+2]&amp;lt;&amp;lt;std::endl;&lt;br /&gt;
&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
void DynamicGrid::update()&lt;br /&gt;
&lt;br /&gt;
{&lt;br /&gt;
&lt;br /&gt;
	removeCustomModelNode();&lt;br /&gt;
&lt;br /&gt;
	delete[] _positions;&lt;br /&gt;
&lt;br /&gt;
	_positions = 0;&lt;br /&gt;
&lt;br /&gt;
	delete[] _normals;&lt;br /&gt;
&lt;br /&gt;
	_normals = 0;&lt;br /&gt;
&lt;br /&gt;
	generatePositions();&lt;br /&gt;
&lt;br /&gt;
	generateNormals();&lt;br /&gt;
&lt;br /&gt;
	addCustomModelNode(-1);&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
void DynamicGrid::saveGridToFile(std::string fileName_)&lt;br /&gt;
&lt;br /&gt;
{&lt;br /&gt;
&lt;br /&gt;
	//std::stringstream fName;&lt;br /&gt;
&lt;br /&gt;
	//fName&amp;lt;&amp;lt;fileName_;&lt;br /&gt;
&lt;br /&gt;
	//fName&amp;lt;&amp;lt;&amp;quot;.d2g&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
	&lt;br /&gt;
&lt;br /&gt;
	std::stringstream ss;&lt;br /&gt;
&lt;br /&gt;
	// magic header&lt;br /&gt;
&lt;br /&gt;
	ss&amp;lt;&amp;lt;&amp;quot;D2SG\n&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
	// the gridsize (important to know!)&lt;br /&gt;
&lt;br /&gt;
	ss&amp;lt;&amp;lt;_gridSize;&lt;br /&gt;
&lt;br /&gt;
	ss&amp;lt;&amp;lt;&amp;quot;\n&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
	// the quadsize (important to know!)&lt;br /&gt;
&lt;br /&gt;
	ss&amp;lt;&amp;lt;_size;&lt;br /&gt;
&lt;br /&gt;
	ss&amp;lt;&amp;lt;&amp;quot;\n&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
	// number of coordinates (most important to know!)&lt;br /&gt;
&lt;br /&gt;
	ss&amp;lt;&amp;lt;(_gridSize*_gridSize*3);&lt;br /&gt;
&lt;br /&gt;
	ss&amp;lt;&amp;lt;&amp;quot;\n&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
	// coordinates&lt;br /&gt;
&lt;br /&gt;
	for (int y=0; y&amp;lt;_gridSize; ++y) {&lt;br /&gt;
&lt;br /&gt;
		for (int x=0; x&amp;lt;_gridSize; ++x) {&lt;br /&gt;
&lt;br /&gt;
			ss&amp;lt;&amp;lt;_grid[y][x].x;&lt;br /&gt;
&lt;br /&gt;
			ss&amp;lt;&amp;lt;&amp;quot;\n&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
			ss&amp;lt;&amp;lt;_grid[y][x].y;&lt;br /&gt;
&lt;br /&gt;
			ss&amp;lt;&amp;lt;&amp;quot;\n&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
			ss&amp;lt;&amp;lt;_grid[y][x].z;&lt;br /&gt;
&lt;br /&gt;
			ss&amp;lt;&amp;lt;&amp;quot;\n&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
		}&lt;br /&gt;
&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	ss&amp;lt;&amp;lt;&amp;quot;\n&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
	std::ofstream dest(fileName_.c_str());&lt;br /&gt;
&lt;br /&gt;
	if (dest.is_open()) {&lt;br /&gt;
&lt;br /&gt;
		dest&amp;lt;&amp;lt;ss.str();&lt;br /&gt;
&lt;br /&gt;
		dest.close();&lt;br /&gt;
&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	std::cout&amp;lt;&amp;lt;&amp;quot;Grid successfully saved to file: &amp;quot;&amp;lt;&amp;lt;fileName_&amp;lt;&amp;lt;std::endl;&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
bool DynamicGrid::readGridFromFile(std::string fileName_)&lt;br /&gt;
&lt;br /&gt;
{&lt;br /&gt;
&lt;br /&gt;
	int numCoordinates;&lt;br /&gt;
&lt;br /&gt;
	std::ifstream inFile;&lt;br /&gt;
&lt;br /&gt;
	inFile.open(fileName_.c_str());&lt;br /&gt;
&lt;br /&gt;
	bool error = false;&lt;br /&gt;
&lt;br /&gt;
	if (!inFile) {&lt;br /&gt;
&lt;br /&gt;
		std::cout&amp;lt;&amp;lt;&amp;quot;Gridfile &amp;quot;&amp;lt;&amp;lt;fileName_&amp;lt;&amp;lt;&amp;quot; could not be found! Creating new grid.&amp;quot;&amp;lt;&amp;lt;std::endl;&lt;br /&gt;
&lt;br /&gt;
		error = true;&lt;br /&gt;
&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	else {&lt;br /&gt;
&lt;br /&gt;
		std::string line;&lt;br /&gt;
&lt;br /&gt;
		if (std::getline(inFile, line)) {&lt;br /&gt;
&lt;br /&gt;
			std::cout&amp;lt;&amp;lt;&amp;quot;Line: &amp;quot;&amp;lt;&amp;lt;line&amp;lt;&amp;lt;std::endl;&lt;br /&gt;
&lt;br /&gt;
			//if (!(line == &amp;quot;D2SG&amp;quot;)) {&lt;br /&gt;
&lt;br /&gt;
			if (line.compare(&amp;quot;D2SG&amp;quot;) != 0){&lt;br /&gt;
&lt;br /&gt;
				std::cout&amp;lt;&amp;lt;&amp;quot;wrong grid-file format &amp;quot;&amp;lt;&amp;lt;line.compare(&amp;quot;D2SG&amp;quot;)&amp;lt;&amp;lt;std::endl;&lt;br /&gt;
&lt;br /&gt;
				error = true;&lt;br /&gt;
&lt;br /&gt;
			}&lt;br /&gt;
&lt;br /&gt;
			else {&lt;br /&gt;
&lt;br /&gt;
				std::cout&amp;lt;&amp;lt;&amp;quot;Valid grid-file found!&amp;quot;&amp;lt;&amp;lt;std::endl;&lt;br /&gt;
&lt;br /&gt;
			}&lt;br /&gt;
&lt;br /&gt;
		}&lt;br /&gt;
&lt;br /&gt;
		if (std::getline(inFile, line)) {&lt;br /&gt;
&lt;br /&gt;
			_gridSize = stringToInt(line);&lt;br /&gt;
&lt;br /&gt;
			//std::cout&amp;lt;&amp;lt;&amp;quot;gridsize: &amp;quot;&amp;lt;&amp;lt;_gridSize&amp;lt;&amp;lt;std::endl;&lt;br /&gt;
&lt;br /&gt;
		}&lt;br /&gt;
&lt;br /&gt;
		else {&lt;br /&gt;
&lt;br /&gt;
			error = true;&lt;br /&gt;
&lt;br /&gt;
		}&lt;br /&gt;
&lt;br /&gt;
		if (std::getline(inFile, line)) {&lt;br /&gt;
&lt;br /&gt;
			_size = stringToInt(line);&lt;br /&gt;
&lt;br /&gt;
			//std::cout&amp;lt;&amp;lt;&amp;quot;quadsize: &amp;quot;&amp;lt;&amp;lt;_size&amp;lt;&amp;lt;std::endl;&lt;br /&gt;
&lt;br /&gt;
		}&lt;br /&gt;
&lt;br /&gt;
		else {&lt;br /&gt;
&lt;br /&gt;
			error = true;&lt;br /&gt;
&lt;br /&gt;
		}&lt;br /&gt;
&lt;br /&gt;
		if (std::getline(inFile, line)) {&lt;br /&gt;
&lt;br /&gt;
			numCoordinates = stringToInt(line);&lt;br /&gt;
&lt;br /&gt;
			//std::cout&amp;lt;&amp;lt;&amp;quot;numCoords: &amp;quot;&amp;lt;&amp;lt;numCoordinates&amp;lt;&amp;lt;std::endl;&lt;br /&gt;
&lt;br /&gt;
		}&lt;br /&gt;
&lt;br /&gt;
		else {&lt;br /&gt;
&lt;br /&gt;
			error = true;&lt;br /&gt;
&lt;br /&gt;
		}&lt;br /&gt;
&lt;br /&gt;
		if (!error) {&lt;br /&gt;
&lt;br /&gt;
			_grid = new Vec3f*[_gridSize];&lt;br /&gt;
&lt;br /&gt;
			for(int y=0; y&amp;lt;_gridSize; ++y) {&lt;br /&gt;
&lt;br /&gt;
				_grid[y] = new Vec3f[_gridSize];&lt;br /&gt;
&lt;br /&gt;
				for (int x=0; x&amp;lt;_gridSize; ++x) {&lt;br /&gt;
&lt;br /&gt;
					Vec3f v;&lt;br /&gt;
&lt;br /&gt;
					if (std::getline(inFile, line)) {&lt;br /&gt;
&lt;br /&gt;
						v.x = stringToFloat(line);&lt;br /&gt;
&lt;br /&gt;
					}&lt;br /&gt;
&lt;br /&gt;
					if (std::getline(inFile, line)) {&lt;br /&gt;
&lt;br /&gt;
						v.y = stringToFloat(line);&lt;br /&gt;
&lt;br /&gt;
					}&lt;br /&gt;
&lt;br /&gt;
					if (std::getline(inFile, line)) {&lt;br /&gt;
&lt;br /&gt;
						v.z = stringToFloat(line);&lt;br /&gt;
&lt;br /&gt;
					}&lt;br /&gt;
&lt;br /&gt;
					_grid[y][x] = v;&lt;br /&gt;
&lt;br /&gt;
				}&lt;br /&gt;
&lt;br /&gt;
			}&lt;br /&gt;
&lt;br /&gt;
		}&lt;br /&gt;
&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	inFile.close();&lt;br /&gt;
&lt;br /&gt;
	if (error) {&lt;br /&gt;
&lt;br /&gt;
		_gridSize = GRIDSIZE;&lt;br /&gt;
&lt;br /&gt;
		_size = 12;&lt;br /&gt;
&lt;br /&gt;
		_grid = 0;&lt;br /&gt;
&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	_numVertices = (_gridSize*_gridSize);&lt;br /&gt;
&lt;br /&gt;
	_numTriangles = ((_gridSize - 1) * (_gridSize - 1)) * 2;&lt;br /&gt;
&lt;br /&gt;
	_numTriangleIndices = _numTriangles * 3;&lt;br /&gt;
&lt;br /&gt;
	_origin = Vec3f(-_size/2*_gridSize, 0, _size/2*_gridSize);&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
	return true;&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
=Usage example=&lt;/div&gt;</summary>
		<author><name>Wakko</name></author>	</entry>

	<entry>
		<id>http://horde3d.org/wiki/index.php?title=Procedurally_generated_geometry_tutorial&amp;diff=565</id>
		<title>Procedurally generated geometry tutorial</title>
		<link rel="alternate" type="text/html" href="http://horde3d.org/wiki/index.php?title=Procedurally_generated_geometry_tutorial&amp;diff=565"/>
				<updated>2009-10-26T11:31:21Z</updated>
		
		<summary type="html">&lt;p&gt;Wakko: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;'''Work in progress   - Due to the current changes in the Horde API this tutorial will be delayed '''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
= Important notes=&lt;br /&gt;
* The code used here has been tested with Horde3D 1.0.0 beta2 and beta3 and will '''NOT''' work with the latest release (beta4)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=Overview=&lt;br /&gt;
==Basic approach==&lt;br /&gt;
To create and display a procedurally generated mesh that, instead of being loaded from a Horde3D Scene node and a geoemtry file(*.scene.xml, *.geo), will be created in-memory by some algorithm, you have to create a mesh first and then &amp;quot;fake&amp;quot; the .geo-file and the scene node itself and pass it to the engine.&lt;br /&gt;
&lt;br /&gt;
To do that you have to create your procedural geometry first. This is easy for simple shapes like single triangles, squares or triangle-strips, but will become way more difficult when we try to generate complex meshes, e.g. when we have a cloud of points in 3D space and have to describe which points make triangles, and which don't (calculating the triangle indices, texture coordinates and normals).&lt;br /&gt;
&lt;br /&gt;
When we have calculated the geometry itself we need to create a char-stream to make Horde believe the geometry has been read from a file and pass it to Horde as a geometry Resource.&lt;br /&gt;
The final step is to create a Horde3D Scene Node from our procedurally generated mesh and render it into our scene.&lt;br /&gt;
[http://musicracer.de/images/Screenshot-1_small.jpg &lt;br /&gt;
This is how it could look like]&lt;br /&gt;
&lt;br /&gt;
=StreamGenerator=&lt;br /&gt;
&lt;br /&gt;
These classes are only for creating the character stream that will contain the geometry resource.&lt;br /&gt;
&lt;br /&gt;
{{CppSourceCode|&lt;br /&gt;
description= StreamGenerator.h| &lt;br /&gt;
code=&lt;br /&gt;
&amp;lt;source lang=&amp;quot;cpp&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
#pragma once&lt;br /&gt;
#include &amp;lt;sstream&amp;gt;&lt;br /&gt;
#include &amp;lt;string&amp;gt;&lt;br /&gt;
#include &amp;lt;iostream&amp;gt;&lt;br /&gt;
&lt;br /&gt;
class StreamGenerator &lt;br /&gt;
{&lt;br /&gt;
public:&lt;br /&gt;
	StreamGenerator();&lt;br /&gt;
	virtual ~StreamGenerator();&lt;br /&gt;
	virtual const char* getStream() = 0;&lt;br /&gt;
	virtual const int getStreamSize() = 0;&lt;br /&gt;
};&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{CppSourceCode|&lt;br /&gt;
description= StreamGenerator.cpp| &lt;br /&gt;
code=&lt;br /&gt;
&amp;lt;source lang=&amp;quot;cpp&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;quot;StreamGenerator.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
StreamGenerator::StreamGenerator() &lt;br /&gt;
{&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
StreamGenerator::~StreamGenerator()&lt;br /&gt;
{&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{CppSourceCode|&lt;br /&gt;
description= GeometryStreamGenerator.h| &lt;br /&gt;
code=&lt;br /&gt;
&amp;lt;source lang=&amp;quot;cpp&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
#pragma once&lt;br /&gt;
#include &amp;quot;StreamGenerator.h&amp;quot;&lt;br /&gt;
#include &amp;quot;CustomGeometry.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
class GeometryStreamGenerator : public StreamGenerator&lt;br /&gt;
{&lt;br /&gt;
private:&lt;br /&gt;
	std::stringstream* ss;&lt;br /&gt;
	void generate();&lt;br /&gt;
	int numVertices, numTriangleIndices;&lt;br /&gt;
	char* _stream;&lt;br /&gt;
	CustomGeometry* _geom;&lt;br /&gt;
&lt;br /&gt;
public:&lt;br /&gt;
	GeometryStreamGenerator(CustomGeometry* geom_);&lt;br /&gt;
	~GeometryStreamGenerator();&lt;br /&gt;
	const char* getStream();&lt;br /&gt;
	const std::stringstream* getStringStream() { return ss; };&lt;br /&gt;
	const int getStreamSize();&lt;br /&gt;
	const int getNumVertices();&lt;br /&gt;
	const int getNumTriangleIndices();&lt;br /&gt;
	void release();&lt;br /&gt;
};&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{CppSourceCode|&lt;br /&gt;
description= GeometryStreamGenerator.cpp| &lt;br /&gt;
code=&lt;br /&gt;
&amp;lt;source lang=&amp;quot;cpp&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;quot;GeometryStreamGenerator.h&amp;quot;&lt;br /&gt;
#include &amp;quot;time.h&amp;quot;&lt;br /&gt;
#include &amp;quot;utMath.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
GeometryStreamGenerator::GeometryStreamGenerator(CustomGeometry* geom_) : _geom(geom_)&lt;br /&gt;
{&lt;br /&gt;
	ss = new std::stringstream();&lt;br /&gt;
	generate();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
GeometryStreamGenerator::~GeometryStreamGenerator()&lt;br /&gt;
{&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void GeometryStreamGenerator::generate()&lt;br /&gt;
{&lt;br /&gt;
	numVertices = _geom-&amp;gt;getNumVertices();&lt;br /&gt;
	numTriangleIndices = _geom-&amp;gt;getNumTriangleIndices();&lt;br /&gt;
	const std::string _magicHeader = &amp;quot;H3DG&amp;quot;;&lt;br /&gt;
	const int _version = 5;&lt;br /&gt;
	const int _numJoints = 1;&lt;br /&gt;
	const float _identityMatrix[] = {	1.0f, 0.0f, 0.0f, 0.0f,  &lt;br /&gt;
						0.0f, 1.0f, 0.0f, 0.0f,  &lt;br /&gt;
						0.0f, 0.0f, 1.0f, 0.0f,  &lt;br /&gt;
						0.0f, 0.0f, 0.0f, 1.0f};&lt;br /&gt;
	const int _numVertexStreams = 3;&lt;br /&gt;
	const int _magicVertices = 0;&lt;br /&gt;
	const int _vertexStreamElementSize = 12;&lt;br /&gt;
	const float* _positions = _geom-&amp;gt;getPositions();&lt;br /&gt;
	const int _magicNormals = 1;&lt;br /&gt;
	const int _normalsStreamElementSize = 6;&lt;br /&gt;
	const float* _normals = _geom-&amp;gt;getNormals();&lt;br /&gt;
	const int _magicTextureCoords1 = 6;&lt;br /&gt;
	const int _texCoordStreamElementSize = 8;&lt;br /&gt;
	const float* _texCoords = _geom-&amp;gt;getTexCoords();&lt;br /&gt;
	const int* _triangleIndices = _geom-&amp;gt;getTriangleIndices();&lt;br /&gt;
	const int _numMorphTragets = 0;&lt;br /&gt;
	// header&lt;br /&gt;
	ss-&amp;gt;write(_magicHeader.c_str(), 4*sizeof(char));&lt;br /&gt;
	ss-&amp;gt;write((char*)&amp;amp;_version, sizeof(int));&lt;br /&gt;
	// joints (mandatory)&lt;br /&gt;
	ss-&amp;gt;write((char*)&amp;amp;_numJoints, sizeof(int));&lt;br /&gt;
	for (int i=0; i&amp;lt;16; ++i) {&lt;br /&gt;
		ss-&amp;gt;write((char*)&amp;amp;_identityMatrix[i], sizeof(float));&lt;br /&gt;
	}&lt;br /&gt;
	// vertices&lt;br /&gt;
	ss-&amp;gt;write((char*)&amp;amp;_numVertexStreams, sizeof(int));&lt;br /&gt;
	const int numVerts = _geom-&amp;gt;getNumVertices();&lt;br /&gt;
	ss-&amp;gt;write((char*)&amp;amp;numVerts, sizeof(int));&lt;br /&gt;
	ss-&amp;gt;write((char*)&amp;amp;_magicVertices, sizeof(int));&lt;br /&gt;
	ss-&amp;gt;write((char*)&amp;amp;_vertexStreamElementSize, sizeof(int));&lt;br /&gt;
	for (int i=0; i&amp;lt;_geom-&amp;gt;getNumVertices()*3; ++i) {&lt;br /&gt;
		ss-&amp;gt;write((char*)&amp;amp;_positions[i], sizeof(float));&lt;br /&gt;
	}&lt;br /&gt;
	// normals&lt;br /&gt;
	ss-&amp;gt;write((char*)&amp;amp;_magicNormals, sizeof(int));&lt;br /&gt;
	ss-&amp;gt;write((char*)&amp;amp;_normalsStreamElementSize, sizeof(int));&lt;br /&gt;
	for (int i=0; i&amp;lt;_geom-&amp;gt;getNumVertices()*3; ++i) {&lt;br /&gt;
		// do not forget to mutliply the value with 32767 and &lt;br /&gt;
		// then convert it to short before writing to the stream&lt;br /&gt;
		const short f = (short)(_normals[i]*32767);&lt;br /&gt;
		ss-&amp;gt;write((char*)&amp;amp;f, sizeof(short));&lt;br /&gt;
	}&lt;br /&gt;
	// texture coordinates&lt;br /&gt;
	ss-&amp;gt;write((char*)&amp;amp;_magicTextureCoords1, sizeof(int));&lt;br /&gt;
	ss-&amp;gt;write((char*)&amp;amp;_texCoordStreamElementSize, sizeof(int));&lt;br /&gt;
	for (int i=0; i&amp;lt;_geom-&amp;gt;getNumVertices()*2; ++i) {&lt;br /&gt;
		ss-&amp;gt;write((char*)&amp;amp;_texCoords[i], sizeof(float));&lt;br /&gt;
	}&lt;br /&gt;
	// triangle indices&lt;br /&gt;
	const int numTriangleIndices = _geom-&amp;gt;getNumTriangleIndices();&lt;br /&gt;
	ss-&amp;gt;write((char*)&amp;amp;numTriangleIndices, sizeof(int));&lt;br /&gt;
	for (int i=0; i&amp;lt;_geom-&amp;gt;getNumTriangleIndices(); ++i) {&lt;br /&gt;
		ss-&amp;gt;write((char*)&amp;amp;_triangleIndices[i], sizeof(int));&lt;br /&gt;
	}&lt;br /&gt;
	ss-&amp;gt;write((char*)&amp;amp;_numMorphTragets, sizeof(int));&lt;br /&gt;
	_stream = new char[ss-&amp;gt;tellp()];&lt;br /&gt;
	ss-&amp;gt;read(_stream, ss-&amp;gt;tellp());&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
const char* GeometryStreamGenerator::getStream()&lt;br /&gt;
{&lt;br /&gt;
	return _stream;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
const int GeometryStreamGenerator::getStreamSize() &lt;br /&gt;
{&lt;br /&gt;
	int t = (int)ss-&amp;gt;tellp();&lt;br /&gt;
	return t;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
const int GeometryStreamGenerator::getNumVertices()&lt;br /&gt;
{&lt;br /&gt;
	return numVertices;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
const int GeometryStreamGenerator::getNumTriangleIndices()&lt;br /&gt;
{&lt;br /&gt;
	return numTriangleIndices;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void GeometryStreamGenerator::release()&lt;br /&gt;
{&lt;br /&gt;
	ss-&amp;gt;flush();&lt;br /&gt;
	ss-&amp;gt;clear();&lt;br /&gt;
	delete ss;&lt;br /&gt;
	ss = 0;&lt;br /&gt;
	delete[] _stream;&lt;br /&gt;
	_stream = 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
=CustomGeometry base class=&lt;br /&gt;
&lt;br /&gt;
Base class for the custom geometry. This class currently contains lots of deprecated stuff, e.g. the update() function. This function was used to update an in-memory gemoetry resource in the &amp;quot;punk-rock&amp;quot;-way. Until Horde3D Beta3 the geometry resources were read-only, so directmanipulation of vertices was impossible. To modify the vertices I had to unload the geometry resource, re-create it with the new vertex-positions and load it into Horde again. '''This is not necessary any more because since Beta4 the geometry resources are not read-only anymore.'''&lt;br /&gt;
&lt;br /&gt;
All custom geometry classes should be derived from this class and implement the abstract functions as needed. (See the examples below)&lt;br /&gt;
&lt;br /&gt;
{{CppSourceCode|&lt;br /&gt;
description= CustomGeometry.h| &lt;br /&gt;
code=&lt;br /&gt;
&amp;lt;source lang=&amp;quot;cpp&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
#pragma once&lt;br /&gt;
/**&lt;br /&gt;
 * Abstract class for custom/dynamic geometry&lt;br /&gt;
 **/&lt;br /&gt;
#include &amp;quot;utMath.h&amp;quot;&lt;br /&gt;
#include &amp;quot;Horde3D.h&amp;quot;&lt;br /&gt;
#include &amp;lt;string&amp;gt;&lt;br /&gt;
&lt;br /&gt;
class CustomGeometry &lt;br /&gt;
{&lt;br /&gt;
protected:&lt;br /&gt;
	float _size;&lt;br /&gt;
	Vec3f _origin;&lt;br /&gt;
	int _numVertices;&lt;br /&gt;
	int _numTriangles;&lt;br /&gt;
	int _numTriangleIndices;&lt;br /&gt;
	float* _positions;&lt;br /&gt;
	float* _normals;&lt;br /&gt;
	float* _texCoords;&lt;br /&gt;
	int* _tIndices;&lt;br /&gt;
	std::string _name;&lt;br /&gt;
	NodeHandle _model;&lt;br /&gt;
	NodeHandle _parent;&lt;br /&gt;
	ResHandle _material;&lt;br /&gt;
	virtual void generatePositions() = 0;&lt;br /&gt;
	virtual void generateNormals() = 0;&lt;br /&gt;
	virtual void generateTexCoords() = 0;&lt;br /&gt;
	virtual void generateTriangleIndices() = 0;&lt;br /&gt;
&lt;br /&gt;
public:&lt;br /&gt;
	CustomGeometry();&lt;br /&gt;
	virtual void generate() = 0;&lt;br /&gt;
	const int getNumVertices() { return _numVertices; }&lt;br /&gt;
	const float* getPositions() { return _positions; }&lt;br /&gt;
	const float* getNormals() { return _normals; }&lt;br /&gt;
	const float* getTexCoords() { return _texCoords; }&lt;br /&gt;
	const int* getTriangleIndices() { return _tIndices; }&lt;br /&gt;
	const int getNumTriangles() { return _numTriangles; }&lt;br /&gt;
	const int getNumTriangleIndices() { return _numTriangleIndices; }&lt;br /&gt;
	void release();&lt;br /&gt;
	const Vec3f getInterpolatedNormal(Vec3f n1_, Vec3f n2_);&lt;br /&gt;
	// pass -1 as the parameter to leave the parent node unchanged&lt;br /&gt;
	void addCustomModelNode(NodeHandle parent_);&lt;br /&gt;
	bool removeCustomModelNode();&lt;br /&gt;
	void setMaterial(ResHandle material_) { _material = material_; }&lt;br /&gt;
	void setParent(NodeHandle parent_) { _parent = parent_; }&lt;br /&gt;
	NodeHandle getModel() { return _model; }&lt;br /&gt;
	ResHandle getMaterial() { return _material; }&lt;br /&gt;
	void update();&lt;br /&gt;
	Vec3f getOrigin() { return _origin; }&lt;br /&gt;
	void setOrigin(Vec3f origin_) { _origin = origin_; }&lt;br /&gt;
	const float getSize() { return _size; }&lt;br /&gt;
};&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{CppSourceCode|&lt;br /&gt;
description= CustomGeometry.cpp| &lt;br /&gt;
code=&lt;br /&gt;
&amp;lt;source lang=&amp;quot;cpp&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;quot;CustomGeometry.h&amp;quot;&lt;br /&gt;
#include &amp;lt;iostream&amp;gt;&lt;br /&gt;
#include &amp;lt;string&amp;gt;&lt;br /&gt;
#include &amp;lt;sstream&amp;gt;&lt;br /&gt;
#include &amp;lt;fstream&amp;gt;&lt;br /&gt;
#include &amp;quot;GeometryStreamGenerator.h&amp;quot;&lt;br /&gt;
#include &amp;quot;Horde3DUtils.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
CustomGeometry::CustomGeometry() : _name(&amp;quot;default&amp;quot;), _size(1)&lt;br /&gt;
{&lt;br /&gt;
	_origin = Vec3f(0, 0, 0);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void CustomGeometry::release()&lt;br /&gt;
{&lt;br /&gt;
	delete[] _positions;&lt;br /&gt;
	_positions = 0;&lt;br /&gt;
	delete[] _normals;&lt;br /&gt;
	_normals = 0;&lt;br /&gt;
	delete[] _texCoords;&lt;br /&gt;
	_texCoords = 0;&lt;br /&gt;
	delete[] _tIndices;&lt;br /&gt;
	_tIndices = 0;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
const Vec3f CustomGeometry::getInterpolatedNormal(Vec3f n1_, Vec3f n2_) &lt;br /&gt;
{&lt;br /&gt;
	Vec3f newNormal = n1_ + n2_;&lt;br /&gt;
	float length = newNormal.length();&lt;br /&gt;
	return newNormal/length;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void CustomGeometry::addCustomModelNode(NodeHandle parent_)&lt;br /&gt;
{&lt;br /&gt;
	//std::stringstream* sa = new std::stringstream();&lt;br /&gt;
	std::stringstream ss;&lt;br /&gt;
	if (parent_ != -1) &lt;br /&gt;
		_parent = parent_;&lt;br /&gt;
	ss&amp;lt;&amp;lt; &amp;quot;customGeometry-&amp;quot;;&lt;br /&gt;
	ss&amp;lt;&amp;lt;_name;&lt;br /&gt;
	GeometryStreamGenerator* gsg = new GeometryStreamGenerator(this);&lt;br /&gt;
	ResHandle customGeoRes = Horde3D::addResource(ResourceTypes::Geometry, ss.str().c_str(), 0);&lt;br /&gt;
	Horde3D::loadResource(customGeoRes, gsg-&amp;gt;getStream(), gsg-&amp;gt;getStreamSize());&lt;br /&gt;
	// model_node_name&lt;br /&gt;
	ss&amp;lt;&amp;lt;&amp;quot;-Node&amp;quot;;&lt;br /&gt;
	_model = Horde3D::addModelNode(_parent, ss.str().c_str(), customGeoRes);&lt;br /&gt;
	// mesh_name&lt;br /&gt;
	ss&amp;lt;&amp;lt;&amp;quot;-Mesh&amp;quot;;&lt;br /&gt;
	Horde3D::addMeshNode(_model, ss.str().c_str(), _material, 0, gsg-&amp;gt;getNumTriangleIndices(), 0, gsg-&amp;gt;getNumVertices()-1);&lt;br /&gt;
	Horde3DUtils::dumpMessages();&lt;br /&gt;
	ss.str(&amp;quot;&amp;quot;);&lt;br /&gt;
	ss.clear();&lt;br /&gt;
	ss.flush();&lt;br /&gt;
	gsg-&amp;gt;release();&lt;br /&gt;
	delete gsg;&lt;br /&gt;
	gsg = 0;&lt;br /&gt;
	//Horde3D::setNodeTransform(_model, _origin.x, _origin.y, _origin.z, 0, 0, 0, 1, 1, 1);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
bool CustomGeometry::removeCustomModelNode()&lt;br /&gt;
{&lt;br /&gt;
	std::stringstream* ss = new std::stringstream();&lt;br /&gt;
	*ss&amp;lt;&amp;lt; &amp;quot;customGeometry-&amp;quot;;&lt;br /&gt;
	*ss&amp;lt;&amp;lt;_name;&lt;br /&gt;
	ResHandle rh = Horde3D::findResource(ResourceTypes::Geometry, ss-&amp;gt;str().c_str());&lt;br /&gt;
	if (Horde3D::isResourceLoaded(rh)) {&lt;br /&gt;
		Horde3D::removeResource(rh);&lt;br /&gt;
		Horde3D::unloadResource(rh);&lt;br /&gt;
		Horde3D::removeNode(_model);&lt;br /&gt;
		Horde3D::releaseUnusedResources();&lt;br /&gt;
		Horde3DUtils::dumpMessages();&lt;br /&gt;
		delete ss;&lt;br /&gt;
		return true;&lt;br /&gt;
	}&lt;br /&gt;
	else &lt;br /&gt;
		return false;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void CustomGeometry::update()&lt;br /&gt;
{&lt;br /&gt;
	removeCustomModelNode();&lt;br /&gt;
	addCustomModelNode(-1);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
=Simple Square=&lt;br /&gt;
&lt;br /&gt;
A simple two-sided (hard-coded) square. This is pretty straight forward and demonstrates how to derive from the CustomGeometry class and how the triangle indices work.&lt;br /&gt;
&lt;br /&gt;
{{CppSourceCode|&lt;br /&gt;
description= DynamicSquare.h| &lt;br /&gt;
code=&lt;br /&gt;
&amp;lt;source lang=&amp;quot;cpp&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
/**&lt;br /&gt;
 * Class representing a square &lt;br /&gt;
 **/&lt;br /&gt;
#pragma once&lt;br /&gt;
#include &amp;quot;CustomGeometry.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
class DynamicSquare : public CustomGeometry&lt;br /&gt;
{&lt;br /&gt;
protected:&lt;br /&gt;
	virtual void generatePositions();&lt;br /&gt;
	virtual void generateNormals();&lt;br /&gt;
	virtual void generateTexCoords();&lt;br /&gt;
	virtual void generateTriangleIndices();&lt;br /&gt;
&lt;br /&gt;
public:&lt;br /&gt;
	DynamicSquare();&lt;br /&gt;
	virtual void generate();&lt;br /&gt;
	DynamicSquare(const float size_, const std::string name_);&lt;br /&gt;
};&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{CppSourceCode|&lt;br /&gt;
description= DynamicSquare.cpp| &lt;br /&gt;
code=&lt;br /&gt;
&amp;lt;source lang=&amp;quot;cpp&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;quot;DynamicSquare.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
DynamicSquare::DynamicSquare() : CustomGeometry()&lt;br /&gt;
{&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
DynamicSquare::DynamicSquare(const float size_, const std::string name_) &lt;br /&gt;
{&lt;br /&gt;
	_size = size_;&lt;br /&gt;
	_name = name_;&lt;br /&gt;
	_numVertices = 8;&lt;br /&gt;
	_numTriangles = 4;&lt;br /&gt;
	_numTriangleIndices = (_numVertices - 2) * 3;&lt;br /&gt;
	//generate();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void DynamicSquare::generate() &lt;br /&gt;
{&lt;br /&gt;
	generatePositions();&lt;br /&gt;
	generateNormals();&lt;br /&gt;
	generateTexCoords();&lt;br /&gt;
	generateTriangleIndices();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void DynamicSquare::generatePositions() &lt;br /&gt;
{&lt;br /&gt;
	_positions = new float[_numVertices * 3 * 2];&lt;br /&gt;
	// front left point (x/y/z)&lt;br /&gt;
	_positions[0] = _origin.x * _size - _size/2;&lt;br /&gt;
	_positions[1] = _origin.y;&lt;br /&gt;
	_positions[2] = _origin.z * _size -_size/2;&lt;br /&gt;
	// front right point (x/y/z)&lt;br /&gt;
	_positions[3] = _origin.x * _size + _size/2;&lt;br /&gt;
	_positions[4] = _origin.y;&lt;br /&gt;
	_positions[5] = _origin.z * _size - _size/2;&lt;br /&gt;
	// back left point (x/y/z)&lt;br /&gt;
	_positions[6] = _origin.x * _size - _size/2;&lt;br /&gt;
	_positions[7] = _origin.y;&lt;br /&gt;
	_positions[8] = _origin.z * _size + _size/2;&lt;br /&gt;
	// back right point (x/y/z)&lt;br /&gt;
	_positions[9] = _origin.x * _size + _size/2;&lt;br /&gt;
	_positions[10] = _origin.y;&lt;br /&gt;
	_positions[11] = _origin.z * _size + _size/2;&lt;br /&gt;
&lt;br /&gt;
        // comment the bottom side if you do not want to have a two-sided sq&lt;br /&gt;
	// bottom sideuare&lt;br /&gt;
	// front left point (x/y/z)&lt;br /&gt;
	_positions[12] = _origin.x * _size - _size/2;&lt;br /&gt;
	_positions[13] = _origin.y-0.5;&lt;br /&gt;
	_positions[14] = _origin.z * _size - _size/2;&lt;br /&gt;
	// front right point (x/y/z)&lt;br /&gt;
	_positions[15] = _origin.x * _size + _size/2;&lt;br /&gt;
	_positions[16] = _origin.y-0.5;&lt;br /&gt;
	_positions[17] = _origin.z * _size - _size/2;&lt;br /&gt;
	// back left point (x/y/z)&lt;br /&gt;
	_positions[18] = _origin.x * _size - _size/2;&lt;br /&gt;
	_positions[19] = _origin.y-0.5;&lt;br /&gt;
	_positions[20] = _origin.z * _size + _size/2;&lt;br /&gt;
	// back right point (x/y/z)&lt;br /&gt;
	_positions[21] = _origin.x * _size + _size/2;&lt;br /&gt;
	_positions[22] = _origin.y-0.5;&lt;br /&gt;
	_positions[23] = _origin.z * _size + _size/2;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void DynamicSquare::generateNormals() &lt;br /&gt;
{&lt;br /&gt;
	_normals = new float[_numVertices * 3*2];&lt;br /&gt;
	for (int i=0; i&amp;lt; 12; i+=3) {&lt;br /&gt;
		_normals[i] = 0;&lt;br /&gt;
		_normals[i+1] = 1;&lt;br /&gt;
		_normals[i+2] = 0;&lt;br /&gt;
	}&lt;br /&gt;
	for (int i=13; i&amp;lt; 24; i+=3) {&lt;br /&gt;
		_normals[i] = 0;&lt;br /&gt;
		_normals[i+1] = -1;&lt;br /&gt;
		_normals[i+2] = 0;&lt;br /&gt;
	}&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void DynamicSquare::generateTexCoords()&lt;br /&gt;
{&lt;br /&gt;
	_texCoords = new float[_numVertices * 2 * 2];&lt;br /&gt;
	_texCoords[0] = 0.0f; &lt;br /&gt;
	_texCoords[1] = 0.0f;&lt;br /&gt;
	_texCoords[2] = 1.0f; &lt;br /&gt;
	_texCoords[3] = 0.0f;&lt;br /&gt;
	_texCoords[4] = 0.0f; &lt;br /&gt;
	_texCoords[5] = 1.0f;&lt;br /&gt;
	_texCoords[6] = 1.0f; &lt;br /&gt;
	_texCoords[7] = 1.0f;&lt;br /&gt;
	_texCoords[8] = 0.0f; &lt;br /&gt;
	_texCoords[9] = 0.0f;&lt;br /&gt;
	_texCoords[10] = 1.0f; &lt;br /&gt;
	_texCoords[11] = 0.0f;&lt;br /&gt;
	_texCoords[12] = 0.0f; &lt;br /&gt;
	_texCoords[13] = 1.0f;&lt;br /&gt;
	_texCoords[14] = 1.0f; &lt;br /&gt;
	_texCoords[15] = 1.0f;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void DynamicSquare::generateTriangleIndices() &lt;br /&gt;
{&lt;br /&gt;
	_tIndices = new int[_numTriangleIndices ];&lt;br /&gt;
	_tIndices[0] = 0;&lt;br /&gt;
	_tIndices[1] = 2;&lt;br /&gt;
	_tIndices[2] = 1;&lt;br /&gt;
	_tIndices[3] = 1;&lt;br /&gt;
	_tIndices[4] = 2;&lt;br /&gt;
	_tIndices[5] = 3;&lt;br /&gt;
	_tIndices[6] = 5;&lt;br /&gt;
	_tIndices[7] = 7;&lt;br /&gt;
	_tIndices[8] = 6;&lt;br /&gt;
	_tIndices[9] = 6;&lt;br /&gt;
	_tIndices[10] = 4;&lt;br /&gt;
	_tIndices[11] = 5;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
=Simple Grid=&lt;br /&gt;
&lt;br /&gt;
All the work above was made to create my own interactive terrain generator(screenshot on top of this page) for a A* pathfinding demonstrator. The Grid-class actually generates a grid of points and allows to extrude each point and re-generate the mesh in realtime by overriding the CustomGeometry function &amp;quot;update()&amp;quot;.&lt;br /&gt;
[http://musicracer.de/images/grid_01_english.png&lt;br /&gt;
This is how it look internally]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=Usage example=&lt;/div&gt;</summary>
		<author><name>Wakko</name></author>	</entry>

	<entry>
		<id>http://horde3d.org/wiki/index.php?title=Procedurally_generated_geometry_tutorial&amp;diff=564</id>
		<title>Procedurally generated geometry tutorial</title>
		<link rel="alternate" type="text/html" href="http://horde3d.org/wiki/index.php?title=Procedurally_generated_geometry_tutorial&amp;diff=564"/>
				<updated>2009-10-26T11:08:10Z</updated>
		
		<summary type="html">&lt;p&gt;Wakko: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;'''Work in progress   - Due to the current changes in the Horde API this tutorial will be delayed '''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
= Important notes=&lt;br /&gt;
* The code used here has been tested with Horde3D 1.0.0 beta2 and beta3 and will '''NOT''' work with the latest release (beta4)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=Overview=&lt;br /&gt;
==Basic approach==&lt;br /&gt;
To create and display a procedurally generated mesh that, instead of being loaded from a Horde3D Scene node and a geoemtry file(*.scene.xml, *.geo), will be created in-memory by some algorithm, you have to create a mesh first and then &amp;quot;fake&amp;quot; the .geo-file and the scene node itself and pass it to the engine.&lt;br /&gt;
&lt;br /&gt;
To do that you have to create your procedural geometry first. This is easy for simple shapes like single triangles, squares or triangle-strips, but will become way more difficult when we try to generate complex meshes, e.g. when we have a cloud of points in 3D space and have to describe which points make triangles, and which don't (calculating the triangle indices, texture coordinates and normals).&lt;br /&gt;
&lt;br /&gt;
When we have calculated the geometry itself we need to create a char-stream to make Horde believe the geometry has been read from a file and pass it to Horde as a geometry Resource.&lt;br /&gt;
The final step is to create a Horde3D Scene Node from our procedurally generated mesh and render it into our scene.&lt;br /&gt;
[http://musicracer.de/images/musicracer_intro.jpg &lt;br /&gt;
This is how it could look like]&lt;br /&gt;
&lt;br /&gt;
=StreamGenerator=&lt;br /&gt;
&lt;br /&gt;
These classes are only for creating the character stream that will contain the geometry resource.&lt;br /&gt;
&lt;br /&gt;
{{CppSourceCode|&lt;br /&gt;
description= StreamGenerator.h| &lt;br /&gt;
code=&lt;br /&gt;
&amp;lt;source lang=&amp;quot;cpp&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
#pragma once&lt;br /&gt;
#include &amp;lt;sstream&amp;gt;&lt;br /&gt;
#include &amp;lt;string&amp;gt;&lt;br /&gt;
#include &amp;lt;iostream&amp;gt;&lt;br /&gt;
&lt;br /&gt;
class StreamGenerator &lt;br /&gt;
{&lt;br /&gt;
public:&lt;br /&gt;
	StreamGenerator();&lt;br /&gt;
	virtual ~StreamGenerator();&lt;br /&gt;
	virtual const char* getStream() = 0;&lt;br /&gt;
	virtual const int getStreamSize() = 0;&lt;br /&gt;
};&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{CppSourceCode|&lt;br /&gt;
description= StreamGenerator.cpp| &lt;br /&gt;
code=&lt;br /&gt;
&amp;lt;source lang=&amp;quot;cpp&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;quot;StreamGenerator.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
StreamGenerator::StreamGenerator() &lt;br /&gt;
{&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
StreamGenerator::~StreamGenerator()&lt;br /&gt;
{&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{CppSourceCode|&lt;br /&gt;
description= GeometryStreamGenerator.h| &lt;br /&gt;
code=&lt;br /&gt;
&amp;lt;source lang=&amp;quot;cpp&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
#pragma once&lt;br /&gt;
#include &amp;quot;StreamGenerator.h&amp;quot;&lt;br /&gt;
#include &amp;quot;CustomGeometry.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
class GeometryStreamGenerator : public StreamGenerator&lt;br /&gt;
{&lt;br /&gt;
private:&lt;br /&gt;
	std::stringstream* ss;&lt;br /&gt;
	void generate();&lt;br /&gt;
	int numVertices, numTriangleIndices;&lt;br /&gt;
	char* _stream;&lt;br /&gt;
	CustomGeometry* _geom;&lt;br /&gt;
&lt;br /&gt;
public:&lt;br /&gt;
	GeometryStreamGenerator(CustomGeometry* geom_);&lt;br /&gt;
	~GeometryStreamGenerator();&lt;br /&gt;
	const char* getStream();&lt;br /&gt;
	const std::stringstream* getStringStream() { return ss; };&lt;br /&gt;
	const int getStreamSize();&lt;br /&gt;
	const int getNumVertices();&lt;br /&gt;
	const int getNumTriangleIndices();&lt;br /&gt;
	void release();&lt;br /&gt;
};&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{CppSourceCode|&lt;br /&gt;
description= GeometryStreamGenerator.cpp| &lt;br /&gt;
code=&lt;br /&gt;
&amp;lt;source lang=&amp;quot;cpp&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;quot;GeometryStreamGenerator.h&amp;quot;&lt;br /&gt;
#include &amp;quot;time.h&amp;quot;&lt;br /&gt;
#include &amp;quot;utMath.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
GeometryStreamGenerator::GeometryStreamGenerator(CustomGeometry* geom_) : _geom(geom_)&lt;br /&gt;
{&lt;br /&gt;
	ss = new std::stringstream();&lt;br /&gt;
	generate();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
GeometryStreamGenerator::~GeometryStreamGenerator()&lt;br /&gt;
{&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void GeometryStreamGenerator::generate()&lt;br /&gt;
{&lt;br /&gt;
	numVertices = _geom-&amp;gt;getNumVertices();&lt;br /&gt;
	numTriangleIndices = _geom-&amp;gt;getNumTriangleIndices();&lt;br /&gt;
	const std::string _magicHeader = &amp;quot;H3DG&amp;quot;;&lt;br /&gt;
	const int _version = 5;&lt;br /&gt;
	const int _numJoints = 1;&lt;br /&gt;
	const float _identityMatrix[] = {	1.0f, 0.0f, 0.0f, 0.0f,  &lt;br /&gt;
						0.0f, 1.0f, 0.0f, 0.0f,  &lt;br /&gt;
						0.0f, 0.0f, 1.0f, 0.0f,  &lt;br /&gt;
						0.0f, 0.0f, 0.0f, 1.0f};&lt;br /&gt;
	const int _numVertexStreams = 3;&lt;br /&gt;
	const int _magicVertices = 0;&lt;br /&gt;
	const int _vertexStreamElementSize = 12;&lt;br /&gt;
	const float* _positions = _geom-&amp;gt;getPositions();&lt;br /&gt;
	const int _magicNormals = 1;&lt;br /&gt;
	const int _normalsStreamElementSize = 6;&lt;br /&gt;
	const float* _normals = _geom-&amp;gt;getNormals();&lt;br /&gt;
	const int _magicTextureCoords1 = 6;&lt;br /&gt;
	const int _texCoordStreamElementSize = 8;&lt;br /&gt;
	const float* _texCoords = _geom-&amp;gt;getTexCoords();&lt;br /&gt;
	const int* _triangleIndices = _geom-&amp;gt;getTriangleIndices();&lt;br /&gt;
	const int _numMorphTragets = 0;&lt;br /&gt;
	// header&lt;br /&gt;
	ss-&amp;gt;write(_magicHeader.c_str(), 4*sizeof(char));&lt;br /&gt;
	ss-&amp;gt;write((char*)&amp;amp;_version, sizeof(int));&lt;br /&gt;
	// joints (mandatory)&lt;br /&gt;
	ss-&amp;gt;write((char*)&amp;amp;_numJoints, sizeof(int));&lt;br /&gt;
	for (int i=0; i&amp;lt;16; ++i) {&lt;br /&gt;
		ss-&amp;gt;write((char*)&amp;amp;_identityMatrix[i], sizeof(float));&lt;br /&gt;
	}&lt;br /&gt;
	// vertices&lt;br /&gt;
	ss-&amp;gt;write((char*)&amp;amp;_numVertexStreams, sizeof(int));&lt;br /&gt;
	const int numVerts = _geom-&amp;gt;getNumVertices();&lt;br /&gt;
	ss-&amp;gt;write((char*)&amp;amp;numVerts, sizeof(int));&lt;br /&gt;
	ss-&amp;gt;write((char*)&amp;amp;_magicVertices, sizeof(int));&lt;br /&gt;
	ss-&amp;gt;write((char*)&amp;amp;_vertexStreamElementSize, sizeof(int));&lt;br /&gt;
	for (int i=0; i&amp;lt;_geom-&amp;gt;getNumVertices()*3; ++i) {&lt;br /&gt;
		ss-&amp;gt;write((char*)&amp;amp;_positions[i], sizeof(float));&lt;br /&gt;
	}&lt;br /&gt;
	// normals&lt;br /&gt;
	ss-&amp;gt;write((char*)&amp;amp;_magicNormals, sizeof(int));&lt;br /&gt;
	ss-&amp;gt;write((char*)&amp;amp;_normalsStreamElementSize, sizeof(int));&lt;br /&gt;
	for (int i=0; i&amp;lt;_geom-&amp;gt;getNumVertices()*3; ++i) {&lt;br /&gt;
		// do not forget to mutliply the value with 32767 and &lt;br /&gt;
		// then convert it to short before writing to the stream&lt;br /&gt;
		const short f = (short)(_normals[i]*32767);&lt;br /&gt;
		ss-&amp;gt;write((char*)&amp;amp;f, sizeof(short));&lt;br /&gt;
	}&lt;br /&gt;
	// texture coordinates&lt;br /&gt;
	ss-&amp;gt;write((char*)&amp;amp;_magicTextureCoords1, sizeof(int));&lt;br /&gt;
	ss-&amp;gt;write((char*)&amp;amp;_texCoordStreamElementSize, sizeof(int));&lt;br /&gt;
	for (int i=0; i&amp;lt;_geom-&amp;gt;getNumVertices()*2; ++i) {&lt;br /&gt;
		ss-&amp;gt;write((char*)&amp;amp;_texCoords[i], sizeof(float));&lt;br /&gt;
	}&lt;br /&gt;
	// triangle indices&lt;br /&gt;
	const int numTriangleIndices = _geom-&amp;gt;getNumTriangleIndices();&lt;br /&gt;
	ss-&amp;gt;write((char*)&amp;amp;numTriangleIndices, sizeof(int));&lt;br /&gt;
	for (int i=0; i&amp;lt;_geom-&amp;gt;getNumTriangleIndices(); ++i) {&lt;br /&gt;
		ss-&amp;gt;write((char*)&amp;amp;_triangleIndices[i], sizeof(int));&lt;br /&gt;
	}&lt;br /&gt;
	ss-&amp;gt;write((char*)&amp;amp;_numMorphTragets, sizeof(int));&lt;br /&gt;
	_stream = new char[ss-&amp;gt;tellp()];&lt;br /&gt;
	ss-&amp;gt;read(_stream, ss-&amp;gt;tellp());&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
const char* GeometryStreamGenerator::getStream()&lt;br /&gt;
{&lt;br /&gt;
	return _stream;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
const int GeometryStreamGenerator::getStreamSize() &lt;br /&gt;
{&lt;br /&gt;
	int t = (int)ss-&amp;gt;tellp();&lt;br /&gt;
	return t;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
const int GeometryStreamGenerator::getNumVertices()&lt;br /&gt;
{&lt;br /&gt;
	return numVertices;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
const int GeometryStreamGenerator::getNumTriangleIndices()&lt;br /&gt;
{&lt;br /&gt;
	return numTriangleIndices;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void GeometryStreamGenerator::release()&lt;br /&gt;
{&lt;br /&gt;
	ss-&amp;gt;flush();&lt;br /&gt;
	ss-&amp;gt;clear();&lt;br /&gt;
	delete ss;&lt;br /&gt;
	ss = 0;&lt;br /&gt;
	delete[] _stream;&lt;br /&gt;
	_stream = 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
=CustomGeometry base class=&lt;br /&gt;
&lt;br /&gt;
Base class for the custom geometry. This class currently contains lots of deprecated stuff, e.g. the update() function. This function was used to update an in-memory gemoetry resource in the &amp;quot;punk-rock&amp;quot;-way. Until Horde3D Beta3 the geometry resources were read-only, so directmanipulation of vertices was impossible. To modify the vertices I had to unload the geometry resource, re-create it with the new vertex-positions and load it into Horde again. '''This is not necessary any more because since Beta4 the geometry resources are not read-only anymore.'''&lt;br /&gt;
&lt;br /&gt;
All custom geometry classes should be derived from this class and implement the abstract functions as needed. (See the examples below)&lt;br /&gt;
&lt;br /&gt;
{{CppSourceCode|&lt;br /&gt;
description= CustomGeometry.h| &lt;br /&gt;
code=&lt;br /&gt;
&amp;lt;source lang=&amp;quot;cpp&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
#pragma once&lt;br /&gt;
/**&lt;br /&gt;
 * Abstract class for custom/dynamic geometry&lt;br /&gt;
 **/&lt;br /&gt;
#include &amp;quot;utMath.h&amp;quot;&lt;br /&gt;
#include &amp;quot;Horde3D.h&amp;quot;&lt;br /&gt;
#include &amp;lt;string&amp;gt;&lt;br /&gt;
&lt;br /&gt;
class CustomGeometry &lt;br /&gt;
{&lt;br /&gt;
protected:&lt;br /&gt;
	float _size;&lt;br /&gt;
	Vec3f _origin;&lt;br /&gt;
	int _numVertices;&lt;br /&gt;
	int _numTriangles;&lt;br /&gt;
	int _numTriangleIndices;&lt;br /&gt;
	float* _positions;&lt;br /&gt;
	float* _normals;&lt;br /&gt;
	float* _texCoords;&lt;br /&gt;
	int* _tIndices;&lt;br /&gt;
	std::string _name;&lt;br /&gt;
	NodeHandle _model;&lt;br /&gt;
	NodeHandle _parent;&lt;br /&gt;
	ResHandle _material;&lt;br /&gt;
	virtual void generatePositions() = 0;&lt;br /&gt;
	virtual void generateNormals() = 0;&lt;br /&gt;
	virtual void generateTexCoords() = 0;&lt;br /&gt;
	virtual void generateTriangleIndices() = 0;&lt;br /&gt;
&lt;br /&gt;
public:&lt;br /&gt;
	CustomGeometry();&lt;br /&gt;
	virtual void generate() = 0;&lt;br /&gt;
	const int getNumVertices() { return _numVertices; }&lt;br /&gt;
	const float* getPositions() { return _positions; }&lt;br /&gt;
	const float* getNormals() { return _normals; }&lt;br /&gt;
	const float* getTexCoords() { return _texCoords; }&lt;br /&gt;
	const int* getTriangleIndices() { return _tIndices; }&lt;br /&gt;
	const int getNumTriangles() { return _numTriangles; }&lt;br /&gt;
	const int getNumTriangleIndices() { return _numTriangleIndices; }&lt;br /&gt;
	void release();&lt;br /&gt;
	const Vec3f getInterpolatedNormal(Vec3f n1_, Vec3f n2_);&lt;br /&gt;
	// pass -1 as the parameter to leave the parent node unchanged&lt;br /&gt;
	void addCustomModelNode(NodeHandle parent_);&lt;br /&gt;
	bool removeCustomModelNode();&lt;br /&gt;
	void setMaterial(ResHandle material_) { _material = material_; }&lt;br /&gt;
	void setParent(NodeHandle parent_) { _parent = parent_; }&lt;br /&gt;
	NodeHandle getModel() { return _model; }&lt;br /&gt;
	ResHandle getMaterial() { return _material; }&lt;br /&gt;
	void update();&lt;br /&gt;
	Vec3f getOrigin() { return _origin; }&lt;br /&gt;
	void setOrigin(Vec3f origin_) { _origin = origin_; }&lt;br /&gt;
	const float getSize() { return _size; }&lt;br /&gt;
};&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{CppSourceCode|&lt;br /&gt;
description= CustomGeometry.cpp| &lt;br /&gt;
code=&lt;br /&gt;
&amp;lt;source lang=&amp;quot;cpp&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;quot;CustomGeometry.h&amp;quot;&lt;br /&gt;
#include &amp;lt;iostream&amp;gt;&lt;br /&gt;
#include &amp;lt;string&amp;gt;&lt;br /&gt;
#include &amp;lt;sstream&amp;gt;&lt;br /&gt;
#include &amp;lt;fstream&amp;gt;&lt;br /&gt;
#include &amp;quot;GeometryStreamGenerator.h&amp;quot;&lt;br /&gt;
#include &amp;quot;Horde3DUtils.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
CustomGeometry::CustomGeometry() : _name(&amp;quot;default&amp;quot;), _size(1)&lt;br /&gt;
{&lt;br /&gt;
	_origin = Vec3f(0, 0, 0);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void CustomGeometry::release()&lt;br /&gt;
{&lt;br /&gt;
	delete[] _positions;&lt;br /&gt;
	_positions = 0;&lt;br /&gt;
	delete[] _normals;&lt;br /&gt;
	_normals = 0;&lt;br /&gt;
	delete[] _texCoords;&lt;br /&gt;
	_texCoords = 0;&lt;br /&gt;
	delete[] _tIndices;&lt;br /&gt;
	_tIndices = 0;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
const Vec3f CustomGeometry::getInterpolatedNormal(Vec3f n1_, Vec3f n2_) &lt;br /&gt;
{&lt;br /&gt;
	Vec3f newNormal = n1_ + n2_;&lt;br /&gt;
	float length = newNormal.length();&lt;br /&gt;
	return newNormal/length;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void CustomGeometry::addCustomModelNode(NodeHandle parent_)&lt;br /&gt;
{&lt;br /&gt;
	//std::stringstream* sa = new std::stringstream();&lt;br /&gt;
	std::stringstream ss;&lt;br /&gt;
	if (parent_ != -1) &lt;br /&gt;
		_parent = parent_;&lt;br /&gt;
	ss&amp;lt;&amp;lt; &amp;quot;customGeometry-&amp;quot;;&lt;br /&gt;
	ss&amp;lt;&amp;lt;_name;&lt;br /&gt;
	GeometryStreamGenerator* gsg = new GeometryStreamGenerator(this);&lt;br /&gt;
	ResHandle customGeoRes = Horde3D::addResource(ResourceTypes::Geometry, ss.str().c_str(), 0);&lt;br /&gt;
	Horde3D::loadResource(customGeoRes, gsg-&amp;gt;getStream(), gsg-&amp;gt;getStreamSize());&lt;br /&gt;
	// model_node_name&lt;br /&gt;
	ss&amp;lt;&amp;lt;&amp;quot;-Node&amp;quot;;&lt;br /&gt;
	_model = Horde3D::addModelNode(_parent, ss.str().c_str(), customGeoRes);&lt;br /&gt;
	// mesh_name&lt;br /&gt;
	ss&amp;lt;&amp;lt;&amp;quot;-Mesh&amp;quot;;&lt;br /&gt;
	Horde3D::addMeshNode(_model, ss.str().c_str(), _material, 0, gsg-&amp;gt;getNumTriangleIndices(), 0, gsg-&amp;gt;getNumVertices()-1);&lt;br /&gt;
	Horde3DUtils::dumpMessages();&lt;br /&gt;
	ss.str(&amp;quot;&amp;quot;);&lt;br /&gt;
	ss.clear();&lt;br /&gt;
	ss.flush();&lt;br /&gt;
	gsg-&amp;gt;release();&lt;br /&gt;
	delete gsg;&lt;br /&gt;
	gsg = 0;&lt;br /&gt;
	//Horde3D::setNodeTransform(_model, _origin.x, _origin.y, _origin.z, 0, 0, 0, 1, 1, 1);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
bool CustomGeometry::removeCustomModelNode()&lt;br /&gt;
{&lt;br /&gt;
	std::stringstream* ss = new std::stringstream();&lt;br /&gt;
	*ss&amp;lt;&amp;lt; &amp;quot;customGeometry-&amp;quot;;&lt;br /&gt;
	*ss&amp;lt;&amp;lt;_name;&lt;br /&gt;
	ResHandle rh = Horde3D::findResource(ResourceTypes::Geometry, ss-&amp;gt;str().c_str());&lt;br /&gt;
	if (Horde3D::isResourceLoaded(rh)) {&lt;br /&gt;
		Horde3D::removeResource(rh);&lt;br /&gt;
		Horde3D::unloadResource(rh);&lt;br /&gt;
		Horde3D::removeNode(_model);&lt;br /&gt;
		Horde3D::releaseUnusedResources();&lt;br /&gt;
		Horde3DUtils::dumpMessages();&lt;br /&gt;
		delete ss;&lt;br /&gt;
		return true;&lt;br /&gt;
	}&lt;br /&gt;
	else &lt;br /&gt;
		return false;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void CustomGeometry::update()&lt;br /&gt;
{&lt;br /&gt;
	removeCustomModelNode();&lt;br /&gt;
	addCustomModelNode(-1);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
=Simple Square=&lt;br /&gt;
&lt;br /&gt;
A simple two-sided (hard-coded) square. This is pretty straight forward and demonstrates how to derive from the CustomGeometry class and how the triangle indices work.&lt;br /&gt;
&lt;br /&gt;
{{CppSourceCode|&lt;br /&gt;
description= DynamicSquare.h| &lt;br /&gt;
code=&lt;br /&gt;
&amp;lt;source lang=&amp;quot;cpp&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
/**&lt;br /&gt;
 * Class representing a square &lt;br /&gt;
 **/&lt;br /&gt;
#pragma once&lt;br /&gt;
#include &amp;quot;CustomGeometry.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
class DynamicSquare : public CustomGeometry&lt;br /&gt;
{&lt;br /&gt;
protected:&lt;br /&gt;
	virtual void generatePositions();&lt;br /&gt;
	virtual void generateNormals();&lt;br /&gt;
	virtual void generateTexCoords();&lt;br /&gt;
	virtual void generateTriangleIndices();&lt;br /&gt;
&lt;br /&gt;
public:&lt;br /&gt;
	DynamicSquare();&lt;br /&gt;
	virtual void generate();&lt;br /&gt;
	DynamicSquare(const float size_, const std::string name_);&lt;br /&gt;
};&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{CppSourceCode|&lt;br /&gt;
description= DynamicSquare.cpp| &lt;br /&gt;
code=&lt;br /&gt;
&amp;lt;source lang=&amp;quot;cpp&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;quot;DynamicSquare.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
DynamicSquare::DynamicSquare() : CustomGeometry()&lt;br /&gt;
{&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
DynamicSquare::DynamicSquare(const float size_, const std::string name_) &lt;br /&gt;
{&lt;br /&gt;
	_size = size_;&lt;br /&gt;
	_name = name_;&lt;br /&gt;
	_numVertices = 8;&lt;br /&gt;
	_numTriangles = 4;&lt;br /&gt;
	_numTriangleIndices = (_numVertices - 2) * 3;&lt;br /&gt;
	//generate();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void DynamicSquare::generate() &lt;br /&gt;
{&lt;br /&gt;
	generatePositions();&lt;br /&gt;
	generateNormals();&lt;br /&gt;
	generateTexCoords();&lt;br /&gt;
	generateTriangleIndices();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void DynamicSquare::generatePositions() &lt;br /&gt;
{&lt;br /&gt;
	_positions = new float[_numVertices * 3 * 2];&lt;br /&gt;
	// front left point (x/y/z)&lt;br /&gt;
	_positions[0] = _origin.x * _size - _size/2;&lt;br /&gt;
	_positions[1] = _origin.y;&lt;br /&gt;
	_positions[2] = _origin.z * _size -_size/2;&lt;br /&gt;
	// front right point (x/y/z)&lt;br /&gt;
	_positions[3] = _origin.x * _size + _size/2;&lt;br /&gt;
	_positions[4] = _origin.y;&lt;br /&gt;
	_positions[5] = _origin.z * _size - _size/2;&lt;br /&gt;
	// back left point (x/y/z)&lt;br /&gt;
	_positions[6] = _origin.x * _size - _size/2;&lt;br /&gt;
	_positions[7] = _origin.y;&lt;br /&gt;
	_positions[8] = _origin.z * _size + _size/2;&lt;br /&gt;
	// back right point (x/y/z)&lt;br /&gt;
	_positions[9] = _origin.x * _size + _size/2;&lt;br /&gt;
	_positions[10] = _origin.y;&lt;br /&gt;
	_positions[11] = _origin.z * _size + _size/2;&lt;br /&gt;
&lt;br /&gt;
        // comment the bottom side if you do not want to have a two-sided sq&lt;br /&gt;
	// bottom sideuare&lt;br /&gt;
	// front left point (x/y/z)&lt;br /&gt;
	_positions[12] = _origin.x * _size - _size/2;&lt;br /&gt;
	_positions[13] = _origin.y-0.5;&lt;br /&gt;
	_positions[14] = _origin.z * _size - _size/2;&lt;br /&gt;
	// front right point (x/y/z)&lt;br /&gt;
	_positions[15] = _origin.x * _size + _size/2;&lt;br /&gt;
	_positions[16] = _origin.y-0.5;&lt;br /&gt;
	_positions[17] = _origin.z * _size - _size/2;&lt;br /&gt;
	// back left point (x/y/z)&lt;br /&gt;
	_positions[18] = _origin.x * _size - _size/2;&lt;br /&gt;
	_positions[19] = _origin.y-0.5;&lt;br /&gt;
	_positions[20] = _origin.z * _size + _size/2;&lt;br /&gt;
	// back right point (x/y/z)&lt;br /&gt;
	_positions[21] = _origin.x * _size + _size/2;&lt;br /&gt;
	_positions[22] = _origin.y-0.5;&lt;br /&gt;
	_positions[23] = _origin.z * _size + _size/2;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void DynamicSquare::generateNormals() &lt;br /&gt;
{&lt;br /&gt;
	_normals = new float[_numVertices * 3*2];&lt;br /&gt;
	for (int i=0; i&amp;lt; 12; i+=3) {&lt;br /&gt;
		_normals[i] = 0;&lt;br /&gt;
		_normals[i+1] = 1;&lt;br /&gt;
		_normals[i+2] = 0;&lt;br /&gt;
	}&lt;br /&gt;
	for (int i=13; i&amp;lt; 24; i+=3) {&lt;br /&gt;
		_normals[i] = 0;&lt;br /&gt;
		_normals[i+1] = -1;&lt;br /&gt;
		_normals[i+2] = 0;&lt;br /&gt;
	}&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void DynamicSquare::generateTexCoords()&lt;br /&gt;
{&lt;br /&gt;
	_texCoords = new float[_numVertices * 2 * 2];&lt;br /&gt;
	_texCoords[0] = 0.0f; &lt;br /&gt;
	_texCoords[1] = 0.0f;&lt;br /&gt;
	_texCoords[2] = 1.0f; &lt;br /&gt;
	_texCoords[3] = 0.0f;&lt;br /&gt;
	_texCoords[4] = 0.0f; &lt;br /&gt;
	_texCoords[5] = 1.0f;&lt;br /&gt;
	_texCoords[6] = 1.0f; &lt;br /&gt;
	_texCoords[7] = 1.0f;&lt;br /&gt;
	_texCoords[8] = 0.0f; &lt;br /&gt;
	_texCoords[9] = 0.0f;&lt;br /&gt;
	_texCoords[10] = 1.0f; &lt;br /&gt;
	_texCoords[11] = 0.0f;&lt;br /&gt;
	_texCoords[12] = 0.0f; &lt;br /&gt;
	_texCoords[13] = 1.0f;&lt;br /&gt;
	_texCoords[14] = 1.0f; &lt;br /&gt;
	_texCoords[15] = 1.0f;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void DynamicSquare::generateTriangleIndices() &lt;br /&gt;
{&lt;br /&gt;
	_tIndices = new int[_numTriangleIndices ];&lt;br /&gt;
	_tIndices[0] = 0;&lt;br /&gt;
	_tIndices[1] = 2;&lt;br /&gt;
	_tIndices[2] = 1;&lt;br /&gt;
	_tIndices[3] = 1;&lt;br /&gt;
	_tIndices[4] = 2;&lt;br /&gt;
	_tIndices[5] = 3;&lt;br /&gt;
	_tIndices[6] = 5;&lt;br /&gt;
	_tIndices[7] = 7;&lt;br /&gt;
	_tIndices[8] = 6;&lt;br /&gt;
	_tIndices[9] = 6;&lt;br /&gt;
	_tIndices[10] = 4;&lt;br /&gt;
	_tIndices[11] = 5;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
=Simple Grid=&lt;br /&gt;
&lt;br /&gt;
=Usage example=&lt;/div&gt;</summary>
		<author><name>Wakko</name></author>	</entry>

	<entry>
		<id>http://horde3d.org/wiki/index.php?title=Procedurally_generated_geometry_tutorial&amp;diff=563</id>
		<title>Procedurally generated geometry tutorial</title>
		<link rel="alternate" type="text/html" href="http://horde3d.org/wiki/index.php?title=Procedurally_generated_geometry_tutorial&amp;diff=563"/>
				<updated>2009-10-26T11:03:19Z</updated>
		
		<summary type="html">&lt;p&gt;Wakko: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;'''Work in progress   - Due to the current changes in the Horde API this tutorial will be delayed '''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
= Important notes=&lt;br /&gt;
* The code used here has been tested with Horde3D 1.0.0 beta2 and beta3 and will '''NOT''' work with the latest release (beta4)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=Overview=&lt;br /&gt;
==Basic approach==&lt;br /&gt;
To create and display a procedurally generated mesh that, instead of being loaded from a Horde3D Scene node and a geoemtry file(*.scene.xml, *.geo), will be created in-memory by some algorithm, you have to create a mesh first and then &amp;quot;fake&amp;quot; the .geo-file and the scene node itself and pass it to the engine.&lt;br /&gt;
&lt;br /&gt;
To do that you have to create your procedural geometry first. This is easy for simple shapes like single triangles, squares or triangle-strips, but will become way more difficult when we try to generate complex meshes, e.g. when we have a cloud of points in 3D space and have to describe which points make triangles, and which don't (calculating the triangle indices, texture coordinates and normals).&lt;br /&gt;
&lt;br /&gt;
When we have calculated the geometry itself we need to create a char-stream to make Horde believe the geometry has been read from a file and pass it to Horde as a geometry Resource.&lt;br /&gt;
The final step is to create a Horde3D Scene Node from our procedurally generated mesh and render it into our scene.&lt;br /&gt;
[http://musicracer.de/images/musicracer_intro.jpg &lt;br /&gt;
This is how it could look like]&lt;br /&gt;
&lt;br /&gt;
=StreamGenerator=&lt;br /&gt;
&lt;br /&gt;
These classes are only for creating the character stream that will contain the geometry resource.&lt;br /&gt;
&lt;br /&gt;
{{CppSourceCode|&lt;br /&gt;
description= StreamGenerator.h| &lt;br /&gt;
code=&lt;br /&gt;
&amp;lt;source lang=&amp;quot;cpp&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
#pragma once&lt;br /&gt;
#include &amp;lt;sstream&amp;gt;&lt;br /&gt;
#include &amp;lt;string&amp;gt;&lt;br /&gt;
#include &amp;lt;iostream&amp;gt;&lt;br /&gt;
&lt;br /&gt;
class StreamGenerator &lt;br /&gt;
{&lt;br /&gt;
public:&lt;br /&gt;
	StreamGenerator();&lt;br /&gt;
	virtual ~StreamGenerator();&lt;br /&gt;
	virtual const char* getStream() = 0;&lt;br /&gt;
	virtual const int getStreamSize() = 0;&lt;br /&gt;
};&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{CppSourceCode|&lt;br /&gt;
description= StreamGenerator.cpp| &lt;br /&gt;
code=&lt;br /&gt;
&amp;lt;source lang=&amp;quot;cpp&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;quot;StreamGenerator.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
StreamGenerator::StreamGenerator() &lt;br /&gt;
{&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
StreamGenerator::~StreamGenerator()&lt;br /&gt;
{&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{CppSourceCode|&lt;br /&gt;
description= GeometryStreamGenerator.h| &lt;br /&gt;
code=&lt;br /&gt;
&amp;lt;source lang=&amp;quot;cpp&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
#pragma once&lt;br /&gt;
#include &amp;quot;StreamGenerator.h&amp;quot;&lt;br /&gt;
#include &amp;quot;CustomGeometry.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
class GeometryStreamGenerator : public StreamGenerator&lt;br /&gt;
{&lt;br /&gt;
private:&lt;br /&gt;
	std::stringstream* ss;&lt;br /&gt;
	void generate();&lt;br /&gt;
	int numVertices, numTriangleIndices;&lt;br /&gt;
	char* _stream;&lt;br /&gt;
	CustomGeometry* _geom;&lt;br /&gt;
&lt;br /&gt;
public:&lt;br /&gt;
	GeometryStreamGenerator(CustomGeometry* geom_);&lt;br /&gt;
	~GeometryStreamGenerator();&lt;br /&gt;
	const char* getStream();&lt;br /&gt;
	const std::stringstream* getStringStream() { return ss; };&lt;br /&gt;
	const int getStreamSize();&lt;br /&gt;
	const int getNumVertices();&lt;br /&gt;
	const int getNumTriangleIndices();&lt;br /&gt;
	void release();&lt;br /&gt;
};&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{CppSourceCode|&lt;br /&gt;
description= GeometryStreamGenerator.cpp| &lt;br /&gt;
code=&lt;br /&gt;
&amp;lt;source lang=&amp;quot;cpp&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;quot;GeometryStreamGenerator.h&amp;quot;&lt;br /&gt;
#include &amp;quot;time.h&amp;quot;&lt;br /&gt;
#include &amp;quot;utMath.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
GeometryStreamGenerator::GeometryStreamGenerator(CustomGeometry* geom_) : _geom(geom_)&lt;br /&gt;
{&lt;br /&gt;
	ss = new std::stringstream();&lt;br /&gt;
	generate();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
GeometryStreamGenerator::~GeometryStreamGenerator()&lt;br /&gt;
{&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void GeometryStreamGenerator::generate()&lt;br /&gt;
{&lt;br /&gt;
	numVertices = _geom-&amp;gt;getNumVertices();&lt;br /&gt;
	numTriangleIndices = _geom-&amp;gt;getNumTriangleIndices();&lt;br /&gt;
	const std::string _magicHeader = &amp;quot;H3DG&amp;quot;;&lt;br /&gt;
	const int _version = 5;&lt;br /&gt;
	const int _numJoints = 1;&lt;br /&gt;
	const float _identityMatrix[] = {	1.0f, 0.0f, 0.0f, 0.0f,  &lt;br /&gt;
						0.0f, 1.0f, 0.0f, 0.0f,  &lt;br /&gt;
						0.0f, 0.0f, 1.0f, 0.0f,  &lt;br /&gt;
						0.0f, 0.0f, 0.0f, 1.0f};&lt;br /&gt;
	const int _numVertexStreams = 3;&lt;br /&gt;
	const int _magicVertices = 0;&lt;br /&gt;
	const int _vertexStreamElementSize = 12;&lt;br /&gt;
	const float* _positions = _geom-&amp;gt;getPositions();&lt;br /&gt;
	const int _magicNormals = 1;&lt;br /&gt;
	const int _normalsStreamElementSize = 6;&lt;br /&gt;
	const float* _normals = _geom-&amp;gt;getNormals();&lt;br /&gt;
	const int _magicTextureCoords1 = 6;&lt;br /&gt;
	const int _texCoordStreamElementSize = 8;&lt;br /&gt;
	const float* _texCoords = _geom-&amp;gt;getTexCoords();&lt;br /&gt;
	const int* _triangleIndices = _geom-&amp;gt;getTriangleIndices();&lt;br /&gt;
	const int _numMorphTragets = 0;&lt;br /&gt;
	// header&lt;br /&gt;
	ss-&amp;gt;write(_magicHeader.c_str(), 4*sizeof(char));&lt;br /&gt;
	ss-&amp;gt;write((char*)&amp;amp;_version, sizeof(int));&lt;br /&gt;
	// joints (mandatory)&lt;br /&gt;
	ss-&amp;gt;write((char*)&amp;amp;_numJoints, sizeof(int));&lt;br /&gt;
	for (int i=0; i&amp;lt;16; ++i) {&lt;br /&gt;
		ss-&amp;gt;write((char*)&amp;amp;_identityMatrix[i], sizeof(float));&lt;br /&gt;
	}&lt;br /&gt;
	// vertices&lt;br /&gt;
	ss-&amp;gt;write((char*)&amp;amp;_numVertexStreams, sizeof(int));&lt;br /&gt;
	const int numVerts = _geom-&amp;gt;getNumVertices();&lt;br /&gt;
	ss-&amp;gt;write((char*)&amp;amp;numVerts, sizeof(int));&lt;br /&gt;
	ss-&amp;gt;write((char*)&amp;amp;_magicVertices, sizeof(int));&lt;br /&gt;
	ss-&amp;gt;write((char*)&amp;amp;_vertexStreamElementSize, sizeof(int));&lt;br /&gt;
	for (int i=0; i&amp;lt;_geom-&amp;gt;getNumVertices()*3; ++i) {&lt;br /&gt;
		ss-&amp;gt;write((char*)&amp;amp;_positions[i], sizeof(float));&lt;br /&gt;
	}&lt;br /&gt;
	// normals&lt;br /&gt;
	ss-&amp;gt;write((char*)&amp;amp;_magicNormals, sizeof(int));&lt;br /&gt;
	ss-&amp;gt;write((char*)&amp;amp;_normalsStreamElementSize, sizeof(int));&lt;br /&gt;
	for (int i=0; i&amp;lt;_geom-&amp;gt;getNumVertices()*3; ++i) {&lt;br /&gt;
		// do not forget to mutliply the value with 32767 and &lt;br /&gt;
		// then convert it to short before writing to the stream&lt;br /&gt;
		const short f = (short)(_normals[i]*32767);&lt;br /&gt;
		ss-&amp;gt;write((char*)&amp;amp;f, sizeof(short));&lt;br /&gt;
	}&lt;br /&gt;
	// texture coordinates&lt;br /&gt;
	ss-&amp;gt;write((char*)&amp;amp;_magicTextureCoords1, sizeof(int));&lt;br /&gt;
	ss-&amp;gt;write((char*)&amp;amp;_texCoordStreamElementSize, sizeof(int));&lt;br /&gt;
	for (int i=0; i&amp;lt;_geom-&amp;gt;getNumVertices()*2; ++i) {&lt;br /&gt;
		ss-&amp;gt;write((char*)&amp;amp;_texCoords[i], sizeof(float));&lt;br /&gt;
	}&lt;br /&gt;
	// triangle indices&lt;br /&gt;
	const int numTriangleIndices = _geom-&amp;gt;getNumTriangleIndices();&lt;br /&gt;
	ss-&amp;gt;write((char*)&amp;amp;numTriangleIndices, sizeof(int));&lt;br /&gt;
	for (int i=0; i&amp;lt;_geom-&amp;gt;getNumTriangleIndices(); ++i) {&lt;br /&gt;
		ss-&amp;gt;write((char*)&amp;amp;_triangleIndices[i], sizeof(int));&lt;br /&gt;
	}&lt;br /&gt;
	ss-&amp;gt;write((char*)&amp;amp;_numMorphTragets, sizeof(int));&lt;br /&gt;
	_stream = new char[ss-&amp;gt;tellp()];&lt;br /&gt;
	ss-&amp;gt;read(_stream, ss-&amp;gt;tellp());&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
const char* GeometryStreamGenerator::getStream()&lt;br /&gt;
{&lt;br /&gt;
	return _stream;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
const int GeometryStreamGenerator::getStreamSize() &lt;br /&gt;
{&lt;br /&gt;
	int t = (int)ss-&amp;gt;tellp();&lt;br /&gt;
	return t;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
const int GeometryStreamGenerator::getNumVertices()&lt;br /&gt;
{&lt;br /&gt;
	return numVertices;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
const int GeometryStreamGenerator::getNumTriangleIndices()&lt;br /&gt;
{&lt;br /&gt;
	return numTriangleIndices;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void GeometryStreamGenerator::release()&lt;br /&gt;
{&lt;br /&gt;
	ss-&amp;gt;flush();&lt;br /&gt;
	ss-&amp;gt;clear();&lt;br /&gt;
	delete ss;&lt;br /&gt;
	ss = 0;&lt;br /&gt;
	delete[] _stream;&lt;br /&gt;
	_stream = 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
=CustomGeometry base class=&lt;br /&gt;
&lt;br /&gt;
Base class for the custom geometry. This class currently contains lots of deprecated stuff, e.g. the update() function. This function was used to update an in-memory gemoetry resource in the &amp;quot;punk-rock&amp;quot;-way. Until Horde3D Beta3 the geometry resources were read-only, so directmanipulation of vertices was impossible. To modify the vertices I had to unload the geometry resource, re-create it with the new vertex-positions and load it into Horde again. '''This is not necessary any more because since Beta4 the geometry resources are not read-only anymore.'''&lt;br /&gt;
&lt;br /&gt;
All custom geometry classes should be derived from this class and implement the abstract functions as needed. (See the examples below)&lt;br /&gt;
&lt;br /&gt;
{{CppSourceCode|&lt;br /&gt;
description= CustomGeometry.h| &lt;br /&gt;
code=&lt;br /&gt;
&amp;lt;source lang=&amp;quot;cpp&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
#pragma once&lt;br /&gt;
/**&lt;br /&gt;
 * Abstract class for custom/dynamic geometry&lt;br /&gt;
 **/&lt;br /&gt;
#include &amp;quot;utMath.h&amp;quot;&lt;br /&gt;
#include &amp;quot;Horde3D.h&amp;quot;&lt;br /&gt;
#include &amp;lt;string&amp;gt;&lt;br /&gt;
&lt;br /&gt;
class CustomGeometry &lt;br /&gt;
{&lt;br /&gt;
protected:&lt;br /&gt;
	float _size;&lt;br /&gt;
	Vec3f _origin;&lt;br /&gt;
	int _numVertices;&lt;br /&gt;
	int _numTriangles;&lt;br /&gt;
	int _numTriangleIndices;&lt;br /&gt;
	float* _positions;&lt;br /&gt;
	float* _normals;&lt;br /&gt;
	float* _texCoords;&lt;br /&gt;
	int* _tIndices;&lt;br /&gt;
	std::string _name;&lt;br /&gt;
	NodeHandle _model;&lt;br /&gt;
	NodeHandle _parent;&lt;br /&gt;
	ResHandle _material;&lt;br /&gt;
	virtual void generatePositions() = 0;&lt;br /&gt;
	virtual void generateNormals() = 0;&lt;br /&gt;
	virtual void generateTexCoords() = 0;&lt;br /&gt;
	virtual void generateTriangleIndices() = 0;&lt;br /&gt;
&lt;br /&gt;
public:&lt;br /&gt;
	CustomGeometry();&lt;br /&gt;
	virtual void generate() = 0;&lt;br /&gt;
	const int getNumVertices() { return _numVertices; }&lt;br /&gt;
	const float* getPositions() { return _positions; }&lt;br /&gt;
	const float* getNormals() { return _normals; }&lt;br /&gt;
	const float* getTexCoords() { return _texCoords; }&lt;br /&gt;
	const int* getTriangleIndices() { return _tIndices; }&lt;br /&gt;
	const int getNumTriangles() { return _numTriangles; }&lt;br /&gt;
	const int getNumTriangleIndices() { return _numTriangleIndices; }&lt;br /&gt;
	void release();&lt;br /&gt;
	const Vec3f getInterpolatedNormal(Vec3f n1_, Vec3f n2_);&lt;br /&gt;
	// pass -1 as the parameter to leave the parent node unchanged&lt;br /&gt;
	void addCustomModelNode(NodeHandle parent_);&lt;br /&gt;
	bool removeCustomModelNode();&lt;br /&gt;
	void setMaterial(ResHandle material_) { _material = material_; }&lt;br /&gt;
	void setParent(NodeHandle parent_) { _parent = parent_; }&lt;br /&gt;
	NodeHandle getModel() { return _model; }&lt;br /&gt;
	ResHandle getMaterial() { return _material; }&lt;br /&gt;
	void update();&lt;br /&gt;
	Vec3f getOrigin() { return _origin; }&lt;br /&gt;
	void setOrigin(Vec3f origin_) { _origin = origin_; }&lt;br /&gt;
	const float getSize() { return _size; }&lt;br /&gt;
};&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{CppSourceCode|&lt;br /&gt;
description= CustomGeometry.cpp| &lt;br /&gt;
code=&lt;br /&gt;
&amp;lt;source lang=&amp;quot;cpp&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;quot;CustomGeometry.h&amp;quot;&lt;br /&gt;
#include &amp;lt;iostream&amp;gt;&lt;br /&gt;
#include &amp;lt;string&amp;gt;&lt;br /&gt;
#include &amp;lt;sstream&amp;gt;&lt;br /&gt;
#include &amp;lt;fstream&amp;gt;&lt;br /&gt;
#include &amp;quot;GeometryStreamGenerator.h&amp;quot;&lt;br /&gt;
#include &amp;quot;Horde3DUtils.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
CustomGeometry::CustomGeometry() : _name(&amp;quot;default&amp;quot;), _size(1)&lt;br /&gt;
{&lt;br /&gt;
	_origin = Vec3f(0, 0, 0);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void CustomGeometry::release()&lt;br /&gt;
{&lt;br /&gt;
	delete[] _positions;&lt;br /&gt;
	_positions = 0;&lt;br /&gt;
	delete[] _normals;&lt;br /&gt;
	_normals = 0;&lt;br /&gt;
	delete[] _texCoords;&lt;br /&gt;
	_texCoords = 0;&lt;br /&gt;
	delete[] _tIndices;&lt;br /&gt;
	_tIndices = 0;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
const Vec3f CustomGeometry::getInterpolatedNormal(Vec3f n1_, Vec3f n2_) &lt;br /&gt;
{&lt;br /&gt;
	Vec3f newNormal = n1_ + n2_;&lt;br /&gt;
	float length = newNormal.length();&lt;br /&gt;
	return newNormal/length;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void CustomGeometry::addCustomModelNode(NodeHandle parent_)&lt;br /&gt;
{&lt;br /&gt;
	//std::stringstream* sa = new std::stringstream();&lt;br /&gt;
	std::stringstream ss;&lt;br /&gt;
	if (parent_ != -1) &lt;br /&gt;
		_parent = parent_;&lt;br /&gt;
	ss&amp;lt;&amp;lt; &amp;quot;customGeometry-&amp;quot;;&lt;br /&gt;
	ss&amp;lt;&amp;lt;_name;&lt;br /&gt;
	GeometryStreamGenerator* gsg = new GeometryStreamGenerator(this);&lt;br /&gt;
	ResHandle customGeoRes = Horde3D::addResource(ResourceTypes::Geometry, ss.str().c_str(), 0);&lt;br /&gt;
	Horde3D::loadResource(customGeoRes, gsg-&amp;gt;getStream(), gsg-&amp;gt;getStreamSize());&lt;br /&gt;
	// model_node_name&lt;br /&gt;
	ss&amp;lt;&amp;lt;&amp;quot;-Node&amp;quot;;&lt;br /&gt;
	_model = Horde3D::addModelNode(_parent, ss.str().c_str(), customGeoRes);&lt;br /&gt;
	// mesh_name&lt;br /&gt;
	ss&amp;lt;&amp;lt;&amp;quot;-Mesh&amp;quot;;&lt;br /&gt;
	Horde3D::addMeshNode(_model, ss.str().c_str(), _material, 0, gsg-&amp;gt;getNumTriangleIndices(), 0, gsg-&amp;gt;getNumVertices()-1);&lt;br /&gt;
	Horde3DUtils::dumpMessages();&lt;br /&gt;
	ss.str(&amp;quot;&amp;quot;);&lt;br /&gt;
	ss.clear();&lt;br /&gt;
	ss.flush();&lt;br /&gt;
	gsg-&amp;gt;release();&lt;br /&gt;
	delete gsg;&lt;br /&gt;
	gsg = 0;&lt;br /&gt;
	//Horde3D::setNodeTransform(_model, _origin.x, _origin.y, _origin.z, 0, 0, 0, 1, 1, 1);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
bool CustomGeometry::removeCustomModelNode()&lt;br /&gt;
{&lt;br /&gt;
	std::stringstream* ss = new std::stringstream();&lt;br /&gt;
	*ss&amp;lt;&amp;lt; &amp;quot;customGeometry-&amp;quot;;&lt;br /&gt;
	*ss&amp;lt;&amp;lt;_name;&lt;br /&gt;
	ResHandle rh = Horde3D::findResource(ResourceTypes::Geometry, ss-&amp;gt;str().c_str());&lt;br /&gt;
	if (Horde3D::isResourceLoaded(rh)) {&lt;br /&gt;
		Horde3D::removeResource(rh);&lt;br /&gt;
		Horde3D::unloadResource(rh);&lt;br /&gt;
		Horde3D::removeNode(_model);&lt;br /&gt;
		Horde3D::releaseUnusedResources();&lt;br /&gt;
		Horde3DUtils::dumpMessages();&lt;br /&gt;
		delete ss;&lt;br /&gt;
		return true;&lt;br /&gt;
	}&lt;br /&gt;
	else &lt;br /&gt;
		return false;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void CustomGeometry::update()&lt;br /&gt;
{&lt;br /&gt;
	removeCustomModelNode();&lt;br /&gt;
	addCustomModelNode(-1);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
=Simple Square=&lt;br /&gt;
&lt;br /&gt;
A simple (not really dynamically generated) hard-coded square. This is pretty straight forward and shows how to derive from the CustomGeometry class and how the triangle indices work.&lt;br /&gt;
&lt;br /&gt;
{{CppSourceCode|&lt;br /&gt;
description= StreamGenerator.h| &lt;br /&gt;
code=&lt;br /&gt;
&amp;lt;source lang=&amp;quot;cpp&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
/**&lt;br /&gt;
&lt;br /&gt;
 * Class representing a square &lt;br /&gt;
&lt;br /&gt;
 **/&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
#pragma once&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
#include &amp;quot;CustomGeometry.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
class DynamicSquare : public CustomGeometry&lt;br /&gt;
&lt;br /&gt;
{&lt;br /&gt;
&lt;br /&gt;
protected:&lt;br /&gt;
&lt;br /&gt;
	virtual void generatePositions();&lt;br /&gt;
&lt;br /&gt;
	virtual void generateNormals();&lt;br /&gt;
&lt;br /&gt;
	virtual void generateTexCoords();&lt;br /&gt;
&lt;br /&gt;
	virtual void generateTriangleIndices();&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
public:&lt;br /&gt;
&lt;br /&gt;
	DynamicSquare();&lt;br /&gt;
&lt;br /&gt;
	virtual void generate();&lt;br /&gt;
&lt;br /&gt;
	DynamicSquare(const float size_, const std::string name_);&lt;br /&gt;
&lt;br /&gt;
	&lt;br /&gt;
&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{CppSourceCode|&lt;br /&gt;
description= StreamGenerator.h| &lt;br /&gt;
code=&lt;br /&gt;
&amp;lt;source lang=&amp;quot;cpp&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;quot;DynamicSquare.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
DynamicSquare::DynamicSquare() : CustomGeometry()&lt;br /&gt;
&lt;br /&gt;
{&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
DynamicSquare::DynamicSquare(const float size_, const std::string name_) &lt;br /&gt;
&lt;br /&gt;
{&lt;br /&gt;
&lt;br /&gt;
	_size = size_;&lt;br /&gt;
&lt;br /&gt;
	_name = name_;&lt;br /&gt;
&lt;br /&gt;
	_numVertices = 8;&lt;br /&gt;
&lt;br /&gt;
	_numTriangles = 4;&lt;br /&gt;
&lt;br /&gt;
	_numTriangleIndices = (_numVertices - 2) * 3;&lt;br /&gt;
&lt;br /&gt;
	//generate();&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
void DynamicSquare::generate() &lt;br /&gt;
&lt;br /&gt;
{&lt;br /&gt;
&lt;br /&gt;
	generatePositions();&lt;br /&gt;
&lt;br /&gt;
	generateNormals();&lt;br /&gt;
&lt;br /&gt;
	generateTexCoords();&lt;br /&gt;
&lt;br /&gt;
	generateTriangleIndices();&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
void DynamicSquare::generatePositions() &lt;br /&gt;
&lt;br /&gt;
{&lt;br /&gt;
&lt;br /&gt;
	_positions = new float[_numVertices * 3 * 2];&lt;br /&gt;
&lt;br /&gt;
	// front left point (x/y/z)&lt;br /&gt;
&lt;br /&gt;
	_positions[0] = _origin.x * _size - _size/2;&lt;br /&gt;
&lt;br /&gt;
	_positions[1] = _origin.y;&lt;br /&gt;
&lt;br /&gt;
	_positions[2] = _origin.z * _size -_size/2;&lt;br /&gt;
&lt;br /&gt;
	// front right point (x/y/z)&lt;br /&gt;
&lt;br /&gt;
	_positions[3] = _origin.x * _size + _size/2;&lt;br /&gt;
&lt;br /&gt;
	_positions[4] = _origin.y;&lt;br /&gt;
&lt;br /&gt;
	_positions[5] = _origin.z * _size - _size/2;&lt;br /&gt;
&lt;br /&gt;
	// back left point (x/y/z)&lt;br /&gt;
&lt;br /&gt;
	_positions[6] = _origin.x * _size - _size/2;&lt;br /&gt;
&lt;br /&gt;
	_positions[7] = _origin.y;&lt;br /&gt;
&lt;br /&gt;
	_positions[8] = _origin.z * _size + _size/2;&lt;br /&gt;
&lt;br /&gt;
	// back right point (x/y/z)&lt;br /&gt;
&lt;br /&gt;
	_positions[9] = _origin.x * _size + _size/2;&lt;br /&gt;
&lt;br /&gt;
	_positions[10] = _origin.y;&lt;br /&gt;
&lt;br /&gt;
	_positions[11] = _origin.z * _size + _size/2;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
	// bottom side&lt;br /&gt;
&lt;br /&gt;
	// front left point (x/y/z)&lt;br /&gt;
&lt;br /&gt;
	_positions[12] = _origin.x * _size - _size/2;&lt;br /&gt;
&lt;br /&gt;
	_positions[13] = _origin.y-0.5;&lt;br /&gt;
&lt;br /&gt;
	_positions[14] = _origin.z * _size - _size/2;&lt;br /&gt;
&lt;br /&gt;
	// front right point (x/y/z)&lt;br /&gt;
&lt;br /&gt;
	_positions[15] = _origin.x * _size + _size/2;&lt;br /&gt;
&lt;br /&gt;
	_positions[16] = _origin.y-0.5;&lt;br /&gt;
&lt;br /&gt;
	_positions[17] = _origin.z * _size - _size/2;&lt;br /&gt;
&lt;br /&gt;
	// back left point (x/y/z)&lt;br /&gt;
&lt;br /&gt;
	_positions[18] = _origin.x * _size - _size/2;&lt;br /&gt;
&lt;br /&gt;
	_positions[19] = _origin.y-0.5;&lt;br /&gt;
&lt;br /&gt;
	_positions[20] = _origin.z * _size + _size/2;&lt;br /&gt;
&lt;br /&gt;
	// back right point (x/y/z)&lt;br /&gt;
&lt;br /&gt;
	_positions[21] = _origin.x * _size + _size/2;&lt;br /&gt;
&lt;br /&gt;
	_positions[22] = _origin.y-0.5;&lt;br /&gt;
&lt;br /&gt;
	_positions[23] = _origin.z * _size + _size/2;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
void DynamicSquare::generateNormals() &lt;br /&gt;
&lt;br /&gt;
{&lt;br /&gt;
&lt;br /&gt;
	_normals = new float[_numVertices * 3*2];&lt;br /&gt;
&lt;br /&gt;
	for (int i=0; i&amp;lt; 12; i+=3) {&lt;br /&gt;
&lt;br /&gt;
		_normals[i] = 0;&lt;br /&gt;
&lt;br /&gt;
		_normals[i+1] = 1;&lt;br /&gt;
&lt;br /&gt;
		_normals[i+2] = 0;&lt;br /&gt;
&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	for (int i=13; i&amp;lt; 24; i+=3) {&lt;br /&gt;
&lt;br /&gt;
		_normals[i] = 0;&lt;br /&gt;
&lt;br /&gt;
		_normals[i+1] = -1;&lt;br /&gt;
&lt;br /&gt;
		_normals[i+2] = 0;&lt;br /&gt;
&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
void DynamicSquare::generateTexCoords()&lt;br /&gt;
&lt;br /&gt;
{&lt;br /&gt;
&lt;br /&gt;
	_texCoords = new float[_numVertices * 2 * 2];&lt;br /&gt;
&lt;br /&gt;
	_texCoords[0] = 0.0f; &lt;br /&gt;
&lt;br /&gt;
	_texCoords[1] = 0.0f;&lt;br /&gt;
&lt;br /&gt;
	_texCoords[2] = 1.0f; &lt;br /&gt;
&lt;br /&gt;
	_texCoords[3] = 0.0f;&lt;br /&gt;
&lt;br /&gt;
	_texCoords[4] = 0.0f; &lt;br /&gt;
&lt;br /&gt;
	_texCoords[5] = 1.0f;&lt;br /&gt;
&lt;br /&gt;
	_texCoords[6] = 1.0f; &lt;br /&gt;
&lt;br /&gt;
	_texCoords[7] = 1.0f;&lt;br /&gt;
&lt;br /&gt;
	_texCoords[8] = 0.0f; &lt;br /&gt;
&lt;br /&gt;
	_texCoords[9] = 0.0f;&lt;br /&gt;
&lt;br /&gt;
	_texCoords[10] = 1.0f; &lt;br /&gt;
&lt;br /&gt;
	_texCoords[11] = 0.0f;&lt;br /&gt;
&lt;br /&gt;
	_texCoords[12] = 0.0f; &lt;br /&gt;
&lt;br /&gt;
	_texCoords[13] = 1.0f;&lt;br /&gt;
&lt;br /&gt;
	_texCoords[14] = 1.0f; &lt;br /&gt;
&lt;br /&gt;
	_texCoords[15] = 1.0f;&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
void DynamicSquare::generateTriangleIndices() &lt;br /&gt;
&lt;br /&gt;
{&lt;br /&gt;
&lt;br /&gt;
	_tIndices = new int[_numTriangleIndices ];&lt;br /&gt;
&lt;br /&gt;
	_tIndices[0] = 0;&lt;br /&gt;
&lt;br /&gt;
	_tIndices[1] = 2;&lt;br /&gt;
&lt;br /&gt;
	_tIndices[2] = 1;&lt;br /&gt;
&lt;br /&gt;
	_tIndices[3] = 1;&lt;br /&gt;
&lt;br /&gt;
	_tIndices[4] = 2;&lt;br /&gt;
&lt;br /&gt;
	_tIndices[5] = 3;&lt;br /&gt;
&lt;br /&gt;
	_tIndices[6] = 5;&lt;br /&gt;
&lt;br /&gt;
	_tIndices[7] = 7;&lt;br /&gt;
&lt;br /&gt;
	_tIndices[8] = 6;&lt;br /&gt;
&lt;br /&gt;
	_tIndices[9] = 6;&lt;br /&gt;
&lt;br /&gt;
	_tIndices[10] = 4;&lt;br /&gt;
&lt;br /&gt;
	_tIndices[11] = 5;&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
=Simple Grid=&lt;br /&gt;
&lt;br /&gt;
=Usage example=&lt;/div&gt;</summary>
		<author><name>Wakko</name></author>	</entry>

	<entry>
		<id>http://horde3d.org/wiki/index.php?title=Procedurally_generated_geometry_tutorial&amp;diff=562</id>
		<title>Procedurally generated geometry tutorial</title>
		<link rel="alternate" type="text/html" href="http://horde3d.org/wiki/index.php?title=Procedurally_generated_geometry_tutorial&amp;diff=562"/>
				<updated>2009-10-26T10:58:16Z</updated>
		
		<summary type="html">&lt;p&gt;Wakko: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Due to the current changes in the Horde API this tutorial will be delayed ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Work in progress'''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
= Important notes=&lt;br /&gt;
* The code used here has been tested with Horde3D 1.0.0 beta2 and beta3 and will '''NOT''' work with the latest release (beta4)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=Overview=&lt;br /&gt;
==Basic approach==&lt;br /&gt;
To create and display a procedurally generated mesh that, instead of being loaded from a Horde3D Scene node and a geoemtry file(*.scene.xml, *.geo), will be created in-memory by some algorithm, you have to create a mesh first and then &amp;quot;fake&amp;quot; the .geo-file and the scene node itself and pass it to the engine.&lt;br /&gt;
&lt;br /&gt;
To do that you have to create your procedural geometry first. This is easy for simple shapes like single triangles, squares or triangle-strips, but will become way more difficult when we try to generate complex meshes, e.g. when we have a cloud of points in 3D space and have to describe which points make triangles, and which don't (calculating the triangle indices, texture coordinates and normals).&lt;br /&gt;
&lt;br /&gt;
When we have calculated the geometry itself we need to create a char-stream to make Horde believe the geometry has been read from a file and pass it to Horde as a geometry Resource.&lt;br /&gt;
The final step is to create a Horde3D Scene Node from our procedurally generated mesh and render it into our scene.&lt;br /&gt;
[http://musicracer.de/images/musicracer_intro.jpg &lt;br /&gt;
This is how it could look like]&lt;br /&gt;
&lt;br /&gt;
=StreamGenerator=&lt;br /&gt;
&lt;br /&gt;
These classes are only for creating the character stream that will contain the geometry resource.&lt;br /&gt;
&lt;br /&gt;
{{CppSourceCode|&lt;br /&gt;
description= StreamGenerator.h| &lt;br /&gt;
code=&lt;br /&gt;
&amp;lt;source lang=&amp;quot;cpp&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
#pragma once&lt;br /&gt;
#include &amp;lt;sstream&amp;gt;&lt;br /&gt;
#include &amp;lt;string&amp;gt;&lt;br /&gt;
#include &amp;lt;iostream&amp;gt;&lt;br /&gt;
&lt;br /&gt;
class StreamGenerator &lt;br /&gt;
{&lt;br /&gt;
public:&lt;br /&gt;
	StreamGenerator();&lt;br /&gt;
	virtual ~StreamGenerator();&lt;br /&gt;
	virtual const char* getStream() = 0;&lt;br /&gt;
	virtual const int getStreamSize() = 0;&lt;br /&gt;
};&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{CppSourceCode|&lt;br /&gt;
description= StreamGenerator.cpp| &lt;br /&gt;
code=&lt;br /&gt;
&amp;lt;source lang=&amp;quot;cpp&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;quot;StreamGenerator.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
StreamGenerator::StreamGenerator() &lt;br /&gt;
{&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
StreamGenerator::~StreamGenerator()&lt;br /&gt;
{&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{CppSourceCode|&lt;br /&gt;
description= GeometryStreamGenerator.h| &lt;br /&gt;
code=&lt;br /&gt;
&amp;lt;source lang=&amp;quot;cpp&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
#pragma once&lt;br /&gt;
#include &amp;quot;StreamGenerator.h&amp;quot;&lt;br /&gt;
#include &amp;quot;CustomGeometry.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
class GeometryStreamGenerator : public StreamGenerator&lt;br /&gt;
{&lt;br /&gt;
private:&lt;br /&gt;
	std::stringstream* ss;&lt;br /&gt;
	void generate();&lt;br /&gt;
	int numVertices, numTriangleIndices;&lt;br /&gt;
	char* _stream;&lt;br /&gt;
	CustomGeometry* _geom;&lt;br /&gt;
&lt;br /&gt;
public:&lt;br /&gt;
	GeometryStreamGenerator(CustomGeometry* geom_);&lt;br /&gt;
	~GeometryStreamGenerator();&lt;br /&gt;
	const char* getStream();&lt;br /&gt;
	const std::stringstream* getStringStream() { return ss; };&lt;br /&gt;
	const int getStreamSize();&lt;br /&gt;
	const int getNumVertices();&lt;br /&gt;
	const int getNumTriangleIndices();&lt;br /&gt;
	void release();&lt;br /&gt;
};&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{CppSourceCode|&lt;br /&gt;
description= GeometryStreamGenerator.cpp| &lt;br /&gt;
code=&lt;br /&gt;
&amp;lt;source lang=&amp;quot;cpp&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;quot;GeometryStreamGenerator.h&amp;quot;&lt;br /&gt;
#include &amp;quot;time.h&amp;quot;&lt;br /&gt;
#include &amp;quot;utMath.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
GeometryStreamGenerator::GeometryStreamGenerator(CustomGeometry* geom_) : _geom(geom_)&lt;br /&gt;
{&lt;br /&gt;
	ss = new std::stringstream();&lt;br /&gt;
	generate();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
GeometryStreamGenerator::~GeometryStreamGenerator()&lt;br /&gt;
{&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void GeometryStreamGenerator::generate()&lt;br /&gt;
{&lt;br /&gt;
	numVertices = _geom-&amp;gt;getNumVertices();&lt;br /&gt;
	numTriangleIndices = _geom-&amp;gt;getNumTriangleIndices();&lt;br /&gt;
	const std::string _magicHeader = &amp;quot;H3DG&amp;quot;;&lt;br /&gt;
	const int _version = 5;&lt;br /&gt;
	const int _numJoints = 1;&lt;br /&gt;
	const float _identityMatrix[] = {	1.0f, 0.0f, 0.0f, 0.0f,  &lt;br /&gt;
						0.0f, 1.0f, 0.0f, 0.0f,  &lt;br /&gt;
						0.0f, 0.0f, 1.0f, 0.0f,  &lt;br /&gt;
						0.0f, 0.0f, 0.0f, 1.0f};&lt;br /&gt;
	const int _numVertexStreams = 3;&lt;br /&gt;
	const int _magicVertices = 0;&lt;br /&gt;
	const int _vertexStreamElementSize = 12;&lt;br /&gt;
	const float* _positions = _geom-&amp;gt;getPositions();&lt;br /&gt;
	const int _magicNormals = 1;&lt;br /&gt;
	const int _normalsStreamElementSize = 6;&lt;br /&gt;
	const float* _normals = _geom-&amp;gt;getNormals();&lt;br /&gt;
	const int _magicTextureCoords1 = 6;&lt;br /&gt;
	const int _texCoordStreamElementSize = 8;&lt;br /&gt;
	const float* _texCoords = _geom-&amp;gt;getTexCoords();&lt;br /&gt;
	const int* _triangleIndices = _geom-&amp;gt;getTriangleIndices();&lt;br /&gt;
	const int _numMorphTragets = 0;&lt;br /&gt;
	// header&lt;br /&gt;
	ss-&amp;gt;write(_magicHeader.c_str(), 4*sizeof(char));&lt;br /&gt;
	ss-&amp;gt;write((char*)&amp;amp;_version, sizeof(int));&lt;br /&gt;
	// joints (mandatory)&lt;br /&gt;
	ss-&amp;gt;write((char*)&amp;amp;_numJoints, sizeof(int));&lt;br /&gt;
	for (int i=0; i&amp;lt;16; ++i) {&lt;br /&gt;
		ss-&amp;gt;write((char*)&amp;amp;_identityMatrix[i], sizeof(float));&lt;br /&gt;
	}&lt;br /&gt;
	// vertices&lt;br /&gt;
	ss-&amp;gt;write((char*)&amp;amp;_numVertexStreams, sizeof(int));&lt;br /&gt;
	const int numVerts = _geom-&amp;gt;getNumVertices();&lt;br /&gt;
	ss-&amp;gt;write((char*)&amp;amp;numVerts, sizeof(int));&lt;br /&gt;
	ss-&amp;gt;write((char*)&amp;amp;_magicVertices, sizeof(int));&lt;br /&gt;
	ss-&amp;gt;write((char*)&amp;amp;_vertexStreamElementSize, sizeof(int));&lt;br /&gt;
	for (int i=0; i&amp;lt;_geom-&amp;gt;getNumVertices()*3; ++i) {&lt;br /&gt;
		ss-&amp;gt;write((char*)&amp;amp;_positions[i], sizeof(float));&lt;br /&gt;
	}&lt;br /&gt;
	// normals&lt;br /&gt;
	ss-&amp;gt;write((char*)&amp;amp;_magicNormals, sizeof(int));&lt;br /&gt;
	ss-&amp;gt;write((char*)&amp;amp;_normalsStreamElementSize, sizeof(int));&lt;br /&gt;
	for (int i=0; i&amp;lt;_geom-&amp;gt;getNumVertices()*3; ++i) {&lt;br /&gt;
		// do not forget to mutliply the value with 32767 and &lt;br /&gt;
		// then convert it to short before writing to the stream&lt;br /&gt;
		const short f = (short)(_normals[i]*32767);&lt;br /&gt;
		ss-&amp;gt;write((char*)&amp;amp;f, sizeof(short));&lt;br /&gt;
	}&lt;br /&gt;
	// texture coordinates&lt;br /&gt;
	ss-&amp;gt;write((char*)&amp;amp;_magicTextureCoords1, sizeof(int));&lt;br /&gt;
	ss-&amp;gt;write((char*)&amp;amp;_texCoordStreamElementSize, sizeof(int));&lt;br /&gt;
	for (int i=0; i&amp;lt;_geom-&amp;gt;getNumVertices()*2; ++i) {&lt;br /&gt;
		ss-&amp;gt;write((char*)&amp;amp;_texCoords[i], sizeof(float));&lt;br /&gt;
	}&lt;br /&gt;
	// triangle indices&lt;br /&gt;
	const int numTriangleIndices = _geom-&amp;gt;getNumTriangleIndices();&lt;br /&gt;
	ss-&amp;gt;write((char*)&amp;amp;numTriangleIndices, sizeof(int));&lt;br /&gt;
	for (int i=0; i&amp;lt;_geom-&amp;gt;getNumTriangleIndices(); ++i) {&lt;br /&gt;
		ss-&amp;gt;write((char*)&amp;amp;_triangleIndices[i], sizeof(int));&lt;br /&gt;
	}&lt;br /&gt;
	ss-&amp;gt;write((char*)&amp;amp;_numMorphTragets, sizeof(int));&lt;br /&gt;
	_stream = new char[ss-&amp;gt;tellp()];&lt;br /&gt;
	ss-&amp;gt;read(_stream, ss-&amp;gt;tellp());&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
const char* GeometryStreamGenerator::getStream()&lt;br /&gt;
{&lt;br /&gt;
	return _stream;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
const int GeometryStreamGenerator::getStreamSize() &lt;br /&gt;
{&lt;br /&gt;
	int t = (int)ss-&amp;gt;tellp();&lt;br /&gt;
	return t;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
const int GeometryStreamGenerator::getNumVertices()&lt;br /&gt;
{&lt;br /&gt;
	return numVertices;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
const int GeometryStreamGenerator::getNumTriangleIndices()&lt;br /&gt;
{&lt;br /&gt;
	return numTriangleIndices;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void GeometryStreamGenerator::release()&lt;br /&gt;
{&lt;br /&gt;
	ss-&amp;gt;flush();&lt;br /&gt;
	ss-&amp;gt;clear();&lt;br /&gt;
	delete ss;&lt;br /&gt;
	ss = 0;&lt;br /&gt;
	delete[] _stream;&lt;br /&gt;
	_stream = 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
=CustomGeometry base class=&lt;br /&gt;
&lt;br /&gt;
Base class for the custom geometry. This class currently contains lots of deprecated stuff, e.g. the update() function. This function was used to update an in-memory gemoetry resource in the &amp;quot;punk-rock&amp;quot;-way. Until Horde3D Beta3 the geometry resources were read-only, so directmanipulation of vertices was impossible. To modify the vertices I had to unload the geometry resource, re-create it with the new vertex-positions and load it into Horde again. '''This is not necessary any more because since Beta4 the geometry resources are not read-only anymore.'''&lt;br /&gt;
&lt;br /&gt;
All custom geometry classes should be derived from this class and implement the abstract functions as needed. (See the examples below)&lt;br /&gt;
&lt;br /&gt;
{{CppSourceCode|&lt;br /&gt;
description= CustomGeometry.h| &lt;br /&gt;
code=&lt;br /&gt;
&amp;lt;source lang=&amp;quot;cpp&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
#pragma once&lt;br /&gt;
/**&lt;br /&gt;
 * Abstract class for custom/dynamic geometry&lt;br /&gt;
 **/&lt;br /&gt;
#include &amp;quot;utMath.h&amp;quot;&lt;br /&gt;
#include &amp;quot;Horde3D.h&amp;quot;&lt;br /&gt;
#include &amp;lt;string&amp;gt;&lt;br /&gt;
&lt;br /&gt;
class CustomGeometry &lt;br /&gt;
{&lt;br /&gt;
protected:&lt;br /&gt;
	float _size;&lt;br /&gt;
	Vec3f _origin;&lt;br /&gt;
	int _numVertices;&lt;br /&gt;
	int _numTriangles;&lt;br /&gt;
	int _numTriangleIndices;&lt;br /&gt;
	float* _positions;&lt;br /&gt;
	float* _normals;&lt;br /&gt;
	float* _texCoords;&lt;br /&gt;
	int* _tIndices;&lt;br /&gt;
	std::string _name;&lt;br /&gt;
	NodeHandle _model;&lt;br /&gt;
	NodeHandle _parent;&lt;br /&gt;
	ResHandle _material;&lt;br /&gt;
	virtual void generatePositions() = 0;&lt;br /&gt;
	virtual void generateNormals() = 0;&lt;br /&gt;
	virtual void generateTexCoords() = 0;&lt;br /&gt;
	virtual void generateTriangleIndices() = 0;&lt;br /&gt;
&lt;br /&gt;
public:&lt;br /&gt;
	CustomGeometry();&lt;br /&gt;
	virtual void generate() = 0;&lt;br /&gt;
	const int getNumVertices() { return _numVertices; }&lt;br /&gt;
	const float* getPositions() { return _positions; }&lt;br /&gt;
	const float* getNormals() { return _normals; }&lt;br /&gt;
	const float* getTexCoords() { return _texCoords; }&lt;br /&gt;
	const int* getTriangleIndices() { return _tIndices; }&lt;br /&gt;
	const int getNumTriangles() { return _numTriangles; }&lt;br /&gt;
	const int getNumTriangleIndices() { return _numTriangleIndices; }&lt;br /&gt;
	void release();&lt;br /&gt;
	const Vec3f getInterpolatedNormal(Vec3f n1_, Vec3f n2_);&lt;br /&gt;
	// pass -1 as the parameter to leave the parent node unchanged&lt;br /&gt;
	void addCustomModelNode(NodeHandle parent_);&lt;br /&gt;
	bool removeCustomModelNode();&lt;br /&gt;
	void setMaterial(ResHandle material_) { _material = material_; }&lt;br /&gt;
	void setParent(NodeHandle parent_) { _parent = parent_; }&lt;br /&gt;
	NodeHandle getModel() { return _model; }&lt;br /&gt;
	ResHandle getMaterial() { return _material; }&lt;br /&gt;
	void update();&lt;br /&gt;
	Vec3f getOrigin() { return _origin; }&lt;br /&gt;
	void setOrigin(Vec3f origin_) { _origin = origin_; }&lt;br /&gt;
	const float getSize() { return _size; }&lt;br /&gt;
};&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{CppSourceCode|&lt;br /&gt;
description= CustomGeometry.cpp| &lt;br /&gt;
code=&lt;br /&gt;
&amp;lt;source lang=&amp;quot;cpp&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;quot;CustomGeometry.h&amp;quot;&lt;br /&gt;
#include &amp;lt;iostream&amp;gt;&lt;br /&gt;
#include &amp;lt;string&amp;gt;&lt;br /&gt;
#include &amp;lt;sstream&amp;gt;&lt;br /&gt;
#include &amp;lt;fstream&amp;gt;&lt;br /&gt;
#include &amp;quot;GeometryStreamGenerator.h&amp;quot;&lt;br /&gt;
#include &amp;quot;Horde3DUtils.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
CustomGeometry::CustomGeometry() : _name(&amp;quot;default&amp;quot;), _size(1)&lt;br /&gt;
{&lt;br /&gt;
	_origin = Vec3f(0, 0, 0);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void CustomGeometry::release()&lt;br /&gt;
{&lt;br /&gt;
	delete[] _positions;&lt;br /&gt;
	_positions = 0;&lt;br /&gt;
	delete[] _normals;&lt;br /&gt;
	_normals = 0;&lt;br /&gt;
	delete[] _texCoords;&lt;br /&gt;
	_texCoords = 0;&lt;br /&gt;
	delete[] _tIndices;&lt;br /&gt;
	_tIndices = 0;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
const Vec3f CustomGeometry::getInterpolatedNormal(Vec3f n1_, Vec3f n2_) &lt;br /&gt;
{&lt;br /&gt;
	Vec3f newNormal = n1_ + n2_;&lt;br /&gt;
	float length = newNormal.length();&lt;br /&gt;
	return newNormal/length;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void CustomGeometry::addCustomModelNode(NodeHandle parent_)&lt;br /&gt;
{&lt;br /&gt;
	//std::stringstream* sa = new std::stringstream();&lt;br /&gt;
	std::stringstream ss;&lt;br /&gt;
	if (parent_ != -1) &lt;br /&gt;
		_parent = parent_;&lt;br /&gt;
	ss&amp;lt;&amp;lt; &amp;quot;customGeometry-&amp;quot;;&lt;br /&gt;
	ss&amp;lt;&amp;lt;_name;&lt;br /&gt;
	GeometryStreamGenerator* gsg = new GeometryStreamGenerator(this);&lt;br /&gt;
	ResHandle customGeoRes = Horde3D::addResource(ResourceTypes::Geometry, ss.str().c_str(), 0);&lt;br /&gt;
	Horde3D::loadResource(customGeoRes, gsg-&amp;gt;getStream(), gsg-&amp;gt;getStreamSize());&lt;br /&gt;
	// model_node_name&lt;br /&gt;
	ss&amp;lt;&amp;lt;&amp;quot;-Node&amp;quot;;&lt;br /&gt;
	_model = Horde3D::addModelNode(_parent, ss.str().c_str(), customGeoRes);&lt;br /&gt;
	// mesh_name&lt;br /&gt;
	ss&amp;lt;&amp;lt;&amp;quot;-Mesh&amp;quot;;&lt;br /&gt;
	Horde3D::addMeshNode(_model, ss.str().c_str(), _material, 0, gsg-&amp;gt;getNumTriangleIndices(), 0, gsg-&amp;gt;getNumVertices()-1);&lt;br /&gt;
	Horde3DUtils::dumpMessages();&lt;br /&gt;
	ss.str(&amp;quot;&amp;quot;);&lt;br /&gt;
	ss.clear();&lt;br /&gt;
	ss.flush();&lt;br /&gt;
	gsg-&amp;gt;release();&lt;br /&gt;
	delete gsg;&lt;br /&gt;
	gsg = 0;&lt;br /&gt;
	//Horde3D::setNodeTransform(_model, _origin.x, _origin.y, _origin.z, 0, 0, 0, 1, 1, 1);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
bool CustomGeometry::removeCustomModelNode()&lt;br /&gt;
{&lt;br /&gt;
	std::stringstream* ss = new std::stringstream();&lt;br /&gt;
	*ss&amp;lt;&amp;lt; &amp;quot;customGeometry-&amp;quot;;&lt;br /&gt;
	*ss&amp;lt;&amp;lt;_name;&lt;br /&gt;
	ResHandle rh = Horde3D::findResource(ResourceTypes::Geometry, ss-&amp;gt;str().c_str());&lt;br /&gt;
	if (Horde3D::isResourceLoaded(rh)) {&lt;br /&gt;
		Horde3D::removeResource(rh);&lt;br /&gt;
		Horde3D::unloadResource(rh);&lt;br /&gt;
		Horde3D::removeNode(_model);&lt;br /&gt;
		Horde3D::releaseUnusedResources();&lt;br /&gt;
		Horde3DUtils::dumpMessages();&lt;br /&gt;
		delete ss;&lt;br /&gt;
		return true;&lt;br /&gt;
	}&lt;br /&gt;
	else &lt;br /&gt;
		return false;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void CustomGeometry::update()&lt;br /&gt;
{&lt;br /&gt;
	removeCustomModelNode();&lt;br /&gt;
	addCustomModelNode(-1);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
=Simple Square=&lt;br /&gt;
&lt;br /&gt;
=Simple Grid=&lt;br /&gt;
&lt;br /&gt;
=Usage example=&lt;/div&gt;</summary>
		<author><name>Wakko</name></author>	</entry>

	<entry>
		<id>http://horde3d.org/wiki/index.php?title=Procedurally_generated_geometry_tutorial&amp;diff=561</id>
		<title>Procedurally generated geometry tutorial</title>
		<link rel="alternate" type="text/html" href="http://horde3d.org/wiki/index.php?title=Procedurally_generated_geometry_tutorial&amp;diff=561"/>
				<updated>2009-10-26T10:53:41Z</updated>
		
		<summary type="html">&lt;p&gt;Wakko: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Due to the current changes in the Horde API this tutorial will be delayed ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Work in progress'''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
= Important notes=&lt;br /&gt;
* The code used here has been tested with Horde3D 1.0.0 beta2 and beta3 and will '''NOT''' work with the latest release (beta4)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=Overview=&lt;br /&gt;
==Basic approach==&lt;br /&gt;
To create and display a procedurally generated mesh that, instead of being loaded from a Horde3D Scene node and a geoemtry file(*.scene.xml, *.geo), will be created in-memory by some algorithm, you have to create a mesh first and then &amp;quot;fake&amp;quot; the .geo-file and the scene node itself and pass it to the engine.&lt;br /&gt;
&lt;br /&gt;
To do that you have to create your procedural geometry first. This is easy for simple shapes like single triangles, squares or triangle-strips, but will become way more difficult when we try to generate complex meshes, e.g. when we have a cloud of points in 3D space and have to describe which points make triangles, and which don't (calculating the triangle indices, texture coordinates and normals).&lt;br /&gt;
&lt;br /&gt;
When we have calculated the geometry itself we need to create a char-stream to make Horde believe the geometry has been read from a file and pass it to Horde as a geometry Resource.&lt;br /&gt;
The final step is to create a Horde3D Scene Node from our procedurally generated mesh and render it into our scene.&lt;br /&gt;
[http://musicracer.de/images/musicracer_intro.jpg &lt;br /&gt;
This is how it could look like]&lt;br /&gt;
&lt;br /&gt;
=StreamGenerator=&lt;br /&gt;
&lt;br /&gt;
These classes are only for creating the character stream that will contain the geometry resource.&lt;br /&gt;
&lt;br /&gt;
{{CppSourceCode|&lt;br /&gt;
description= StreamGenerator.h| &lt;br /&gt;
code=&lt;br /&gt;
&amp;lt;source lang=&amp;quot;cpp&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
#pragma once&lt;br /&gt;
#include &amp;lt;sstream&amp;gt;&lt;br /&gt;
#include &amp;lt;string&amp;gt;&lt;br /&gt;
#include &amp;lt;iostream&amp;gt;&lt;br /&gt;
&lt;br /&gt;
class StreamGenerator &lt;br /&gt;
{&lt;br /&gt;
public:&lt;br /&gt;
	StreamGenerator();&lt;br /&gt;
	virtual ~StreamGenerator();&lt;br /&gt;
	virtual const char* getStream() = 0;&lt;br /&gt;
	virtual const int getStreamSize() = 0;&lt;br /&gt;
};&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{CppSourceCode|&lt;br /&gt;
description= StreamGenerator.cpp| &lt;br /&gt;
code=&lt;br /&gt;
&amp;lt;source lang=&amp;quot;cpp&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;quot;StreamGenerator.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
StreamGenerator::StreamGenerator() &lt;br /&gt;
{&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
StreamGenerator::~StreamGenerator()&lt;br /&gt;
{&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{CppSourceCode|&lt;br /&gt;
description= GeometryStreamGenerator.h| &lt;br /&gt;
code=&lt;br /&gt;
&amp;lt;source lang=&amp;quot;cpp&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
#pragma once&lt;br /&gt;
#include &amp;quot;StreamGenerator.h&amp;quot;&lt;br /&gt;
#include &amp;quot;CustomGeometry.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
class GeometryStreamGenerator : public StreamGenerator&lt;br /&gt;
{&lt;br /&gt;
private:&lt;br /&gt;
	std::stringstream* ss;&lt;br /&gt;
	void generate();&lt;br /&gt;
	int numVertices, numTriangleIndices;&lt;br /&gt;
	char* _stream;&lt;br /&gt;
	CustomGeometry* _geom;&lt;br /&gt;
&lt;br /&gt;
public:&lt;br /&gt;
	GeometryStreamGenerator(CustomGeometry* geom_);&lt;br /&gt;
	~GeometryStreamGenerator();&lt;br /&gt;
	const char* getStream();&lt;br /&gt;
	const std::stringstream* getStringStream() { return ss; };&lt;br /&gt;
	const int getStreamSize();&lt;br /&gt;
	const int getNumVertices();&lt;br /&gt;
	const int getNumTriangleIndices();&lt;br /&gt;
	void release();&lt;br /&gt;
};&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{CppSourceCode|&lt;br /&gt;
description= GeometryStreamGenerator.cpp| &lt;br /&gt;
code=&lt;br /&gt;
&amp;lt;source lang=&amp;quot;cpp&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;quot;GeometryStreamGenerator.h&amp;quot;&lt;br /&gt;
#include &amp;quot;time.h&amp;quot;&lt;br /&gt;
#include &amp;quot;utMath.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
GeometryStreamGenerator::GeometryStreamGenerator(CustomGeometry* geom_) : _geom(geom_)&lt;br /&gt;
{&lt;br /&gt;
	ss = new std::stringstream();&lt;br /&gt;
	generate();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
GeometryStreamGenerator::~GeometryStreamGenerator()&lt;br /&gt;
{&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void GeometryStreamGenerator::generate()&lt;br /&gt;
{&lt;br /&gt;
	numVertices = _geom-&amp;gt;getNumVertices();&lt;br /&gt;
	numTriangleIndices = _geom-&amp;gt;getNumTriangleIndices();&lt;br /&gt;
	const std::string _magicHeader = &amp;quot;H3DG&amp;quot;;&lt;br /&gt;
	const int _version = 5;&lt;br /&gt;
	const int _numJoints = 1;&lt;br /&gt;
	const float _identityMatrix[] = {	1.0f, 0.0f, 0.0f, 0.0f,  &lt;br /&gt;
						0.0f, 1.0f, 0.0f, 0.0f,  &lt;br /&gt;
						0.0f, 0.0f, 1.0f, 0.0f,  &lt;br /&gt;
						0.0f, 0.0f, 0.0f, 1.0f};&lt;br /&gt;
	const int _numVertexStreams = 3;&lt;br /&gt;
	const int _magicVertices = 0;&lt;br /&gt;
	const int _vertexStreamElementSize = 12;&lt;br /&gt;
	const float* _positions = _geom-&amp;gt;getPositions();&lt;br /&gt;
	const int _magicNormals = 1;&lt;br /&gt;
	const int _normalsStreamElementSize = 6;&lt;br /&gt;
	const float* _normals = _geom-&amp;gt;getNormals();&lt;br /&gt;
	const int _magicTextureCoords1 = 6;&lt;br /&gt;
	const int _texCoordStreamElementSize = 8;&lt;br /&gt;
	const float* _texCoords = _geom-&amp;gt;getTexCoords();&lt;br /&gt;
	const int* _triangleIndices = _geom-&amp;gt;getTriangleIndices();&lt;br /&gt;
	const int _numMorphTragets = 0;&lt;br /&gt;
	// header&lt;br /&gt;
	ss-&amp;gt;write(_magicHeader.c_str(), 4*sizeof(char));&lt;br /&gt;
	ss-&amp;gt;write((char*)&amp;amp;_version, sizeof(int));&lt;br /&gt;
	// joints (mandatory)&lt;br /&gt;
	ss-&amp;gt;write((char*)&amp;amp;_numJoints, sizeof(int));&lt;br /&gt;
	for (int i=0; i&amp;lt;16; ++i) {&lt;br /&gt;
		ss-&amp;gt;write((char*)&amp;amp;_identityMatrix[i], sizeof(float));&lt;br /&gt;
	}&lt;br /&gt;
	// vertices&lt;br /&gt;
	ss-&amp;gt;write((char*)&amp;amp;_numVertexStreams, sizeof(int));&lt;br /&gt;
	const int numVerts = _geom-&amp;gt;getNumVertices();&lt;br /&gt;
	ss-&amp;gt;write((char*)&amp;amp;numVerts, sizeof(int));&lt;br /&gt;
	ss-&amp;gt;write((char*)&amp;amp;_magicVertices, sizeof(int));&lt;br /&gt;
	ss-&amp;gt;write((char*)&amp;amp;_vertexStreamElementSize, sizeof(int));&lt;br /&gt;
	for (int i=0; i&amp;lt;_geom-&amp;gt;getNumVertices()*3; ++i) {&lt;br /&gt;
		ss-&amp;gt;write((char*)&amp;amp;_positions[i], sizeof(float));&lt;br /&gt;
	}&lt;br /&gt;
	// normals&lt;br /&gt;
	ss-&amp;gt;write((char*)&amp;amp;_magicNormals, sizeof(int));&lt;br /&gt;
	ss-&amp;gt;write((char*)&amp;amp;_normalsStreamElementSize, sizeof(int));&lt;br /&gt;
	for (int i=0; i&amp;lt;_geom-&amp;gt;getNumVertices()*3; ++i) {&lt;br /&gt;
		// do not forget to mutliply the value with 32767 and &lt;br /&gt;
		// then convert it to short before writing to the stream&lt;br /&gt;
		const short f = (short)(_normals[i]*32767);&lt;br /&gt;
		ss-&amp;gt;write((char*)&amp;amp;f, sizeof(short));&lt;br /&gt;
	}&lt;br /&gt;
	// texture coordinates&lt;br /&gt;
	ss-&amp;gt;write((char*)&amp;amp;_magicTextureCoords1, sizeof(int));&lt;br /&gt;
	ss-&amp;gt;write((char*)&amp;amp;_texCoordStreamElementSize, sizeof(int));&lt;br /&gt;
	for (int i=0; i&amp;lt;_geom-&amp;gt;getNumVertices()*2; ++i) {&lt;br /&gt;
		ss-&amp;gt;write((char*)&amp;amp;_texCoords[i], sizeof(float));&lt;br /&gt;
	}&lt;br /&gt;
	// triangle indices&lt;br /&gt;
	const int numTriangleIndices = _geom-&amp;gt;getNumTriangleIndices();&lt;br /&gt;
	ss-&amp;gt;write((char*)&amp;amp;numTriangleIndices, sizeof(int));&lt;br /&gt;
	for (int i=0; i&amp;lt;_geom-&amp;gt;getNumTriangleIndices(); ++i) {&lt;br /&gt;
		ss-&amp;gt;write((char*)&amp;amp;_triangleIndices[i], sizeof(int));&lt;br /&gt;
	}&lt;br /&gt;
	ss-&amp;gt;write((char*)&amp;amp;_numMorphTragets, sizeof(int));&lt;br /&gt;
	_stream = new char[ss-&amp;gt;tellp()];&lt;br /&gt;
	ss-&amp;gt;read(_stream, ss-&amp;gt;tellp());&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
const char* GeometryStreamGenerator::getStream()&lt;br /&gt;
{&lt;br /&gt;
	return _stream;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
const int GeometryStreamGenerator::getStreamSize() &lt;br /&gt;
{&lt;br /&gt;
	int t = (int)ss-&amp;gt;tellp();&lt;br /&gt;
	return t;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
const int GeometryStreamGenerator::getNumVertices()&lt;br /&gt;
{&lt;br /&gt;
	return numVertices;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
const int GeometryStreamGenerator::getNumTriangleIndices()&lt;br /&gt;
{&lt;br /&gt;
	return numTriangleIndices;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void GeometryStreamGenerator::release()&lt;br /&gt;
{&lt;br /&gt;
	ss-&amp;gt;flush();&lt;br /&gt;
	ss-&amp;gt;clear();&lt;br /&gt;
	delete ss;&lt;br /&gt;
	ss = 0;&lt;br /&gt;
	delete[] _stream;&lt;br /&gt;
	_stream = 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
=CustomGeometry base class=&lt;br /&gt;
&lt;br /&gt;
Base class for the custom geometry. This class currently contains lots of deprecated stuff, e.g. the update() function. This function was used to update an in-memory gemoetry resource in the &amp;quot;punk-rock&amp;quot;-way. Until Horde3D Beta3 the geometry resources were read-only, so directmanipulation of vertices was impossible. To modify the vertices I had to unload the geometry resource, re-create it with the new vertex-positions and load it into Horde again. '''This is not necessary any more because since Beta4 the geometry resources are not read-only anymore.'''&lt;br /&gt;
&lt;br /&gt;
All custom geometry classes should be derived from this class and implement the abstract functions as needed. (See the examples below)&lt;br /&gt;
&lt;br /&gt;
{{CppSourceCode|&lt;br /&gt;
description= CustomGeometry.h| &lt;br /&gt;
code=&lt;br /&gt;
&amp;lt;source lang=&amp;quot;cpp&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
#pragma once&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
/**&lt;br /&gt;
&lt;br /&gt;
 * Abstract class for custom/dynamic geometry&lt;br /&gt;
&lt;br /&gt;
 **/&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
#include &amp;quot;utMath.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
#include &amp;quot;Horde3D.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
#include &amp;lt;string&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
class CustomGeometry &lt;br /&gt;
{&lt;br /&gt;
&lt;br /&gt;
protected:&lt;br /&gt;
&lt;br /&gt;
	float _size;&lt;br /&gt;
&lt;br /&gt;
	Vec3f _origin;&lt;br /&gt;
&lt;br /&gt;
	int _numVertices;&lt;br /&gt;
&lt;br /&gt;
	int _numTriangles;&lt;br /&gt;
&lt;br /&gt;
	int _numTriangleIndices;&lt;br /&gt;
&lt;br /&gt;
	float* _positions;&lt;br /&gt;
&lt;br /&gt;
	float* _normals;&lt;br /&gt;
&lt;br /&gt;
	float* _texCoords;&lt;br /&gt;
&lt;br /&gt;
	int* _tIndices;&lt;br /&gt;
&lt;br /&gt;
	std::string _name;&lt;br /&gt;
&lt;br /&gt;
	NodeHandle _model;&lt;br /&gt;
&lt;br /&gt;
	NodeHandle _parent;&lt;br /&gt;
&lt;br /&gt;
	ResHandle _material;&lt;br /&gt;
&lt;br /&gt;
	virtual void generatePositions() = 0;&lt;br /&gt;
&lt;br /&gt;
	virtual void generateNormals() = 0;&lt;br /&gt;
&lt;br /&gt;
	virtual void generateTexCoords() = 0;&lt;br /&gt;
&lt;br /&gt;
	virtual void generateTriangleIndices() = 0;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
public:&lt;br /&gt;
&lt;br /&gt;
	CustomGeometry();&lt;br /&gt;
&lt;br /&gt;
	virtual void generate() = 0;&lt;br /&gt;
&lt;br /&gt;
	const int getNumVertices() { return _numVertices; }&lt;br /&gt;
&lt;br /&gt;
	const float* getPositions() { return _positions; }&lt;br /&gt;
&lt;br /&gt;
	const float* getNormals() { return _normals; }&lt;br /&gt;
&lt;br /&gt;
	const float* getTexCoords() { return _texCoords; }&lt;br /&gt;
&lt;br /&gt;
	const int* getTriangleIndices() { return _tIndices; }&lt;br /&gt;
&lt;br /&gt;
	const int getNumTriangles() { return _numTriangles; }&lt;br /&gt;
&lt;br /&gt;
	const int getNumTriangleIndices() { return _numTriangleIndices; }&lt;br /&gt;
&lt;br /&gt;
	void release();&lt;br /&gt;
&lt;br /&gt;
	const Vec3f getInterpolatedNormal(Vec3f n1_, Vec3f n2_);&lt;br /&gt;
&lt;br /&gt;
	// pass -1 as the parameter to leave the parent node unchanged&lt;br /&gt;
&lt;br /&gt;
	void addCustomModelNode(NodeHandle parent_);&lt;br /&gt;
&lt;br /&gt;
	bool removeCustomModelNode();&lt;br /&gt;
&lt;br /&gt;
	void setMaterial(ResHandle material_) { _material = material_; }&lt;br /&gt;
&lt;br /&gt;
	void setParent(NodeHandle parent_) { _parent = parent_; }&lt;br /&gt;
&lt;br /&gt;
	NodeHandle getModel() { return _model; }&lt;br /&gt;
&lt;br /&gt;
	ResHandle getMaterial() { return _material; }&lt;br /&gt;
&lt;br /&gt;
	void update();&lt;br /&gt;
&lt;br /&gt;
	Vec3f getOrigin() { return _origin; }&lt;br /&gt;
&lt;br /&gt;
	void setOrigin(Vec3f origin_) { _origin = origin_; }&lt;br /&gt;
&lt;br /&gt;
	const float getSize() { return _size; }&lt;br /&gt;
&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{CppSourceCode|&lt;br /&gt;
description= CustomGeometry.cpp| &lt;br /&gt;
code=&lt;br /&gt;
&amp;lt;source lang=&amp;quot;cpp&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;quot;CustomGeometry.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
#include &amp;lt;iostream&amp;gt;&lt;br /&gt;
&lt;br /&gt;
#include &amp;lt;string&amp;gt;&lt;br /&gt;
&lt;br /&gt;
#include &amp;lt;sstream&amp;gt;&lt;br /&gt;
&lt;br /&gt;
#include &amp;lt;fstream&amp;gt;&lt;br /&gt;
&lt;br /&gt;
#include &amp;quot;GeometryStreamGenerator.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
#include &amp;quot;Horde3DUtils.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
CustomGeometry::CustomGeometry() : _name(&amp;quot;default&amp;quot;), _size(1)&lt;br /&gt;
&lt;br /&gt;
{&lt;br /&gt;
&lt;br /&gt;
	_origin = Vec3f(0, 0, 0);&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
void CustomGeometry::release()&lt;br /&gt;
&lt;br /&gt;
{&lt;br /&gt;
&lt;br /&gt;
	delete[] _positions;&lt;br /&gt;
&lt;br /&gt;
	_positions = 0;&lt;br /&gt;
&lt;br /&gt;
	delete[] _normals;&lt;br /&gt;
&lt;br /&gt;
	_normals = 0;&lt;br /&gt;
&lt;br /&gt;
	delete[] _texCoords;&lt;br /&gt;
&lt;br /&gt;
	_texCoords = 0;&lt;br /&gt;
&lt;br /&gt;
	delete[] _tIndices;&lt;br /&gt;
&lt;br /&gt;
	_tIndices = 0;&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
const Vec3f CustomGeometry::getInterpolatedNormal(Vec3f n1_, Vec3f n2_) &lt;br /&gt;
&lt;br /&gt;
{&lt;br /&gt;
&lt;br /&gt;
	Vec3f newNormal = n1_ + n2_;&lt;br /&gt;
&lt;br /&gt;
	float length = newNormal.length();&lt;br /&gt;
&lt;br /&gt;
	return newNormal/length;&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
void CustomGeometry::addCustomModelNode(NodeHandle parent_)&lt;br /&gt;
&lt;br /&gt;
{&lt;br /&gt;
&lt;br /&gt;
	//std::stringstream* sa = new std::stringstream();&lt;br /&gt;
&lt;br /&gt;
	std::stringstream ss;&lt;br /&gt;
&lt;br /&gt;
	if (parent_ != -1) &lt;br /&gt;
&lt;br /&gt;
		_parent = parent_;&lt;br /&gt;
&lt;br /&gt;
	ss&amp;lt;&amp;lt; &amp;quot;customGeometry-&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
	ss&amp;lt;&amp;lt;_name;&lt;br /&gt;
&lt;br /&gt;
	GeometryStreamGenerator* gsg = new GeometryStreamGenerator(this);&lt;br /&gt;
&lt;br /&gt;
	ResHandle customGeoRes = Horde3D::addResource(ResourceTypes::Geometry, ss.str().c_str(), 0);&lt;br /&gt;
&lt;br /&gt;
	Horde3D::loadResource(customGeoRes, gsg-&amp;gt;getStream(), gsg-&amp;gt;getStreamSize());&lt;br /&gt;
&lt;br /&gt;
	// model_node_name&lt;br /&gt;
&lt;br /&gt;
	ss&amp;lt;&amp;lt;&amp;quot;-Node&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
	_model = Horde3D::addModelNode(_parent, ss.str().c_str(), customGeoRes);&lt;br /&gt;
&lt;br /&gt;
	// mesh_name&lt;br /&gt;
&lt;br /&gt;
	ss&amp;lt;&amp;lt;&amp;quot;-Mesh&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
	Horde3D::addMeshNode(_model, ss.str().c_str(), _material, 0, gsg-&amp;gt;getNumTriangleIndices(), 0, gsg-&amp;gt;getNumVertices()-1);&lt;br /&gt;
&lt;br /&gt;
	Horde3DUtils::dumpMessages();&lt;br /&gt;
&lt;br /&gt;
	ss.str(&amp;quot;&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
	ss.clear();&lt;br /&gt;
&lt;br /&gt;
	ss.flush();&lt;br /&gt;
&lt;br /&gt;
	gsg-&amp;gt;release();&lt;br /&gt;
&lt;br /&gt;
	delete gsg;&lt;br /&gt;
&lt;br /&gt;
	gsg = 0;&lt;br /&gt;
&lt;br /&gt;
	//Horde3D::setNodeTransform(_model, _origin.x, _origin.y, _origin.z, 0, 0, 0, 1, 1, 1);&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
bool CustomGeometry::removeCustomModelNode()&lt;br /&gt;
&lt;br /&gt;
{&lt;br /&gt;
&lt;br /&gt;
	std::stringstream* ss = new std::stringstream();&lt;br /&gt;
&lt;br /&gt;
	*ss&amp;lt;&amp;lt; &amp;quot;customGeometry-&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
	*ss&amp;lt;&amp;lt;_name;&lt;br /&gt;
&lt;br /&gt;
	ResHandle rh = Horde3D::findResource(ResourceTypes::Geometry, ss-&amp;gt;str().c_str());&lt;br /&gt;
&lt;br /&gt;
	if (Horde3D::isResourceLoaded(rh)) {&lt;br /&gt;
&lt;br /&gt;
		Horde3D::removeResource(rh);&lt;br /&gt;
&lt;br /&gt;
		Horde3D::unloadResource(rh);&lt;br /&gt;
&lt;br /&gt;
		Horde3D::removeNode(_model);&lt;br /&gt;
&lt;br /&gt;
		Horde3D::releaseUnusedResources();&lt;br /&gt;
&lt;br /&gt;
		Horde3DUtils::dumpMessages();&lt;br /&gt;
&lt;br /&gt;
		delete ss;&lt;br /&gt;
&lt;br /&gt;
		return true;&lt;br /&gt;
&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	else &lt;br /&gt;
&lt;br /&gt;
		return false;&lt;br /&gt;
&lt;br /&gt;
	&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
void CustomGeometry::update()&lt;br /&gt;
&lt;br /&gt;
{&lt;br /&gt;
&lt;br /&gt;
	removeCustomModelNode();&lt;br /&gt;
&lt;br /&gt;
	addCustomModelNode(-1);&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
=Simple Square=&lt;br /&gt;
&lt;br /&gt;
=Simple Grid=&lt;br /&gt;
&lt;br /&gt;
=Usage example=&lt;/div&gt;</summary>
		<author><name>Wakko</name></author>	</entry>

	<entry>
		<id>http://horde3d.org/wiki/index.php?title=Procedurally_generated_geometry_tutorial&amp;diff=560</id>
		<title>Procedurally generated geometry tutorial</title>
		<link rel="alternate" type="text/html" href="http://horde3d.org/wiki/index.php?title=Procedurally_generated_geometry_tutorial&amp;diff=560"/>
				<updated>2009-10-26T10:39:46Z</updated>
		
		<summary type="html">&lt;p&gt;Wakko: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Due to the current changes in the Horde API this tutorial will be delayed ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Work in progress'''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
= Important notes=&lt;br /&gt;
* The code used here has been tested with Horde3D 1.0.0 beta2 and beta3 and will '''NOT''' work with the latest release (beta4)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=Overview=&lt;br /&gt;
==Basic approach==&lt;br /&gt;
To create and display a procedurally generated mesh that, instead of being loaded from a Horde3D Scene node and a geoemtry file(*.scene.xml, *.geo), will be created in-memory by some algorithm, you have to create a mesh first and then &amp;quot;fake&amp;quot; the .geo-file and the scene node itself and pass it to the engine.&lt;br /&gt;
&lt;br /&gt;
To do that you have to create your procedural geometry first. This is easy for simple shapes like single triangles, squares or triangle-strips, but will become way more difficult when we try to generate complex meshes, e.g. when we have a cloud of points in 3D space and have to describe which points make triangles, and which don't (calculating the triangle indices, texture coordinates and normals).&lt;br /&gt;
&lt;br /&gt;
When we have calculated the geometry itself we need to create a char-stream to make Horde believe the geometry has been read from a file and pass it to Horde as a geometry Resource.&lt;br /&gt;
The final step is to create a Horde3D Scene Node from our procedurally generated mesh and render it into our scene.&lt;br /&gt;
[http://musicracer.de/images/musicracer_intro.jpg &lt;br /&gt;
This is how it could look like]&lt;br /&gt;
&lt;br /&gt;
=StreamGenerator=&lt;br /&gt;
{{CppSourceCode|&lt;br /&gt;
description= StreamGenerator.h| &lt;br /&gt;
code=&lt;br /&gt;
&amp;lt;source lang=&amp;quot;cpp&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
#pragma once&lt;br /&gt;
#include &amp;lt;sstream&amp;gt;&lt;br /&gt;
#include &amp;lt;string&amp;gt;&lt;br /&gt;
#include &amp;lt;iostream&amp;gt;&lt;br /&gt;
&lt;br /&gt;
class StreamGenerator &lt;br /&gt;
{&lt;br /&gt;
public:&lt;br /&gt;
	StreamGenerator();&lt;br /&gt;
	virtual ~StreamGenerator();&lt;br /&gt;
	virtual const char* getStream() = 0;&lt;br /&gt;
	virtual const int getStreamSize() = 0;&lt;br /&gt;
};&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{CppSourceCode|&lt;br /&gt;
description= StreamGenerator.cpp| &lt;br /&gt;
code=&lt;br /&gt;
&amp;lt;source lang=&amp;quot;cpp&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;quot;StreamGenerator.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
StreamGenerator::StreamGenerator() &lt;br /&gt;
{&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
StreamGenerator::~StreamGenerator()&lt;br /&gt;
{&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{CppSourceCode|&lt;br /&gt;
description= GeometryStreamGenerator.h| &lt;br /&gt;
code=&lt;br /&gt;
&amp;lt;source lang=&amp;quot;cpp&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
#pragma once&lt;br /&gt;
#include &amp;quot;StreamGenerator.h&amp;quot;&lt;br /&gt;
#include &amp;quot;CustomGeometry.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
class GeometryStreamGenerator : public StreamGenerator&lt;br /&gt;
{&lt;br /&gt;
private:&lt;br /&gt;
	std::stringstream* ss;&lt;br /&gt;
	void generate();&lt;br /&gt;
	int numVertices, numTriangleIndices;&lt;br /&gt;
	char* _stream;&lt;br /&gt;
	CustomGeometry* _geom;&lt;br /&gt;
&lt;br /&gt;
public:&lt;br /&gt;
	GeometryStreamGenerator(CustomGeometry* geom_);&lt;br /&gt;
	~GeometryStreamGenerator();&lt;br /&gt;
	const char* getStream();&lt;br /&gt;
	const std::stringstream* getStringStream() { return ss; };&lt;br /&gt;
	const int getStreamSize();&lt;br /&gt;
	const int getNumVertices();&lt;br /&gt;
	const int getNumTriangleIndices();&lt;br /&gt;
	void release();&lt;br /&gt;
};&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{CppSourceCode|&lt;br /&gt;
description= GeometryStreamGenerator.cpp| &lt;br /&gt;
code=&lt;br /&gt;
&amp;lt;source lang=&amp;quot;cpp&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;quot;GeometryStreamGenerator.h&amp;quot;&lt;br /&gt;
#include &amp;quot;time.h&amp;quot;&lt;br /&gt;
#include &amp;quot;utMath.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
GeometryStreamGenerator::GeometryStreamGenerator(CustomGeometry* geom_) : _geom(geom_)&lt;br /&gt;
{&lt;br /&gt;
	ss = new std::stringstream();&lt;br /&gt;
	generate();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
GeometryStreamGenerator::~GeometryStreamGenerator()&lt;br /&gt;
{&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void GeometryStreamGenerator::generate()&lt;br /&gt;
{&lt;br /&gt;
	numVertices = _geom-&amp;gt;getNumVertices();&lt;br /&gt;
	numTriangleIndices = _geom-&amp;gt;getNumTriangleIndices();&lt;br /&gt;
	const std::string _magicHeader = &amp;quot;H3DG&amp;quot;;&lt;br /&gt;
	const int _version = 5;&lt;br /&gt;
	const int _numJoints = 1;&lt;br /&gt;
	const float _identityMatrix[] = {	1.0f, 0.0f, 0.0f, 0.0f,  &lt;br /&gt;
						0.0f, 1.0f, 0.0f, 0.0f,  &lt;br /&gt;
						0.0f, 0.0f, 1.0f, 0.0f,  &lt;br /&gt;
						0.0f, 0.0f, 0.0f, 1.0f};&lt;br /&gt;
	const int _numVertexStreams = 3;&lt;br /&gt;
	const int _magicVertices = 0;&lt;br /&gt;
	const int _vertexStreamElementSize = 12;&lt;br /&gt;
	const float* _positions = _geom-&amp;gt;getPositions();&lt;br /&gt;
	const int _magicNormals = 1;&lt;br /&gt;
	const int _normalsStreamElementSize = 6;&lt;br /&gt;
	const float* _normals = _geom-&amp;gt;getNormals();&lt;br /&gt;
	const int _magicTextureCoords1 = 6;&lt;br /&gt;
	const int _texCoordStreamElementSize = 8;&lt;br /&gt;
	const float* _texCoords = _geom-&amp;gt;getTexCoords();&lt;br /&gt;
	const int* _triangleIndices = _geom-&amp;gt;getTriangleIndices();&lt;br /&gt;
	const int _numMorphTragets = 0;&lt;br /&gt;
	// header&lt;br /&gt;
	ss-&amp;gt;write(_magicHeader.c_str(), 4*sizeof(char));&lt;br /&gt;
	ss-&amp;gt;write((char*)&amp;amp;_version, sizeof(int));&lt;br /&gt;
	// joints (mandatory)&lt;br /&gt;
	ss-&amp;gt;write((char*)&amp;amp;_numJoints, sizeof(int));&lt;br /&gt;
	for (int i=0; i&amp;lt;16; ++i) {&lt;br /&gt;
		ss-&amp;gt;write((char*)&amp;amp;_identityMatrix[i], sizeof(float));&lt;br /&gt;
	}&lt;br /&gt;
	// vertices&lt;br /&gt;
	ss-&amp;gt;write((char*)&amp;amp;_numVertexStreams, sizeof(int));&lt;br /&gt;
	const int numVerts = _geom-&amp;gt;getNumVertices();&lt;br /&gt;
	ss-&amp;gt;write((char*)&amp;amp;numVerts, sizeof(int));&lt;br /&gt;
	ss-&amp;gt;write((char*)&amp;amp;_magicVertices, sizeof(int));&lt;br /&gt;
	ss-&amp;gt;write((char*)&amp;amp;_vertexStreamElementSize, sizeof(int));&lt;br /&gt;
	for (int i=0; i&amp;lt;_geom-&amp;gt;getNumVertices()*3; ++i) {&lt;br /&gt;
		ss-&amp;gt;write((char*)&amp;amp;_positions[i], sizeof(float));&lt;br /&gt;
	}&lt;br /&gt;
	// normals&lt;br /&gt;
	ss-&amp;gt;write((char*)&amp;amp;_magicNormals, sizeof(int));&lt;br /&gt;
	ss-&amp;gt;write((char*)&amp;amp;_normalsStreamElementSize, sizeof(int));&lt;br /&gt;
	for (int i=0; i&amp;lt;_geom-&amp;gt;getNumVertices()*3; ++i) {&lt;br /&gt;
		// do not forget to mutliply the value with 32767 and &lt;br /&gt;
		// then convert it to short before writing to the stream&lt;br /&gt;
		const short f = (short)(_normals[i]*32767);&lt;br /&gt;
		ss-&amp;gt;write((char*)&amp;amp;f, sizeof(short));&lt;br /&gt;
	}&lt;br /&gt;
	// texture coordinates&lt;br /&gt;
	ss-&amp;gt;write((char*)&amp;amp;_magicTextureCoords1, sizeof(int));&lt;br /&gt;
	ss-&amp;gt;write((char*)&amp;amp;_texCoordStreamElementSize, sizeof(int));&lt;br /&gt;
	for (int i=0; i&amp;lt;_geom-&amp;gt;getNumVertices()*2; ++i) {&lt;br /&gt;
		ss-&amp;gt;write((char*)&amp;amp;_texCoords[i], sizeof(float));&lt;br /&gt;
	}&lt;br /&gt;
	// triangle indices&lt;br /&gt;
	const int numTriangleIndices = _geom-&amp;gt;getNumTriangleIndices();&lt;br /&gt;
	ss-&amp;gt;write((char*)&amp;amp;numTriangleIndices, sizeof(int));&lt;br /&gt;
	for (int i=0; i&amp;lt;_geom-&amp;gt;getNumTriangleIndices(); ++i) {&lt;br /&gt;
		ss-&amp;gt;write((char*)&amp;amp;_triangleIndices[i], sizeof(int));&lt;br /&gt;
	}&lt;br /&gt;
	ss-&amp;gt;write((char*)&amp;amp;_numMorphTragets, sizeof(int));&lt;br /&gt;
	_stream = new char[ss-&amp;gt;tellp()];&lt;br /&gt;
	ss-&amp;gt;read(_stream, ss-&amp;gt;tellp());&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
const char* GeometryStreamGenerator::getStream()&lt;br /&gt;
{&lt;br /&gt;
	return _stream;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
const int GeometryStreamGenerator::getStreamSize() &lt;br /&gt;
{&lt;br /&gt;
	int t = (int)ss-&amp;gt;tellp();&lt;br /&gt;
	return t;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
const int GeometryStreamGenerator::getNumVertices()&lt;br /&gt;
{&lt;br /&gt;
	return numVertices;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
const int GeometryStreamGenerator::getNumTriangleIndices()&lt;br /&gt;
{&lt;br /&gt;
	return numTriangleIndices;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void GeometryStreamGenerator::release()&lt;br /&gt;
{&lt;br /&gt;
	ss-&amp;gt;flush();&lt;br /&gt;
	ss-&amp;gt;clear();&lt;br /&gt;
	delete ss;&lt;br /&gt;
	ss = 0;&lt;br /&gt;
	delete[] _stream;&lt;br /&gt;
	_stream = 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
=CustomGeometry base class=&lt;br /&gt;
&lt;br /&gt;
=Simple Square=&lt;br /&gt;
&lt;br /&gt;
=Simple Grid=&lt;br /&gt;
&lt;br /&gt;
=Usage example=&lt;/div&gt;</summary>
		<author><name>Wakko</name></author>	</entry>

	<entry>
		<id>http://horde3d.org/wiki/index.php?title=Procedurally_generated_geometry_tutorial&amp;diff=559</id>
		<title>Procedurally generated geometry tutorial</title>
		<link rel="alternate" type="text/html" href="http://horde3d.org/wiki/index.php?title=Procedurally_generated_geometry_tutorial&amp;diff=559"/>
				<updated>2009-10-26T10:38:47Z</updated>
		
		<summary type="html">&lt;p&gt;Wakko: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Due to the current changes in the Horde API this tutorial will be delayed ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Work in progress'''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
= Important notes=&lt;br /&gt;
* The code used here has been tested with Horde3D 1.0.0 beta2 and beta3 and will '''NOT''' work with the latest release (beta4)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=Overview=&lt;br /&gt;
==Basic approach==&lt;br /&gt;
To create and display a procedurally generated mesh that, instead of being loaded from a Horde3D Scene node and a geoemtry file(*.scene.xml, *.geo), will be created in-memory by some algorithm, you have to create a mesh first and then &amp;quot;fake&amp;quot; the .geo-file and the scene node itself and pass it to the engine.&lt;br /&gt;
&lt;br /&gt;
To do that you have to create your procedural geometry first. This is easy for simple shapes like single triangles, squares or triangle-strips, but will become way more difficult when we try to generate complex meshes, e.g. when we have a cloud of points in 3D space and have to describe which points make triangles, and which don't (calculating the triangle indices, texture coordinates and normals).&lt;br /&gt;
&lt;br /&gt;
When we have calculated the geometry itself we need to create a char-stream to make Horde believe the geometry has been read from a file and pass it to Horde as a geometry Resource.&lt;br /&gt;
The final step is to create a Horde3D Scene Node from our procedurally generated mesh and render it into our scene.&lt;br /&gt;
[http://musicracer.de/images/musicracer_intro.jpg &lt;br /&gt;
This is how it could look like]&lt;br /&gt;
&lt;br /&gt;
=StreamGenerator=&lt;br /&gt;
{{CppSourceCode|&lt;br /&gt;
description= StreamGenerator.h| &lt;br /&gt;
code=&lt;br /&gt;
&amp;lt;source lang=&amp;quot;cpp&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
#pragma once&lt;br /&gt;
#include &amp;lt;sstream&amp;gt;&lt;br /&gt;
#include &amp;lt;string&amp;gt;&lt;br /&gt;
#include &amp;lt;iostream&amp;gt;&lt;br /&gt;
&lt;br /&gt;
class StreamGenerator &lt;br /&gt;
{&lt;br /&gt;
public:&lt;br /&gt;
	StreamGenerator();&lt;br /&gt;
	virtual ~StreamGenerator();&lt;br /&gt;
	virtual const char* getStream() = 0;&lt;br /&gt;
	virtual const int getStreamSize() = 0;&lt;br /&gt;
};&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{CppSourceCode|&lt;br /&gt;
description= StreamGenerator.h| &lt;br /&gt;
code=&lt;br /&gt;
&amp;lt;source lang=&amp;quot;cpp&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;quot;StreamGenerator.cpp&amp;quot;&lt;br /&gt;
&lt;br /&gt;
StreamGenerator::StreamGenerator() &lt;br /&gt;
{&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
StreamGenerator::~StreamGenerator()&lt;br /&gt;
{&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{CppSourceCode|&lt;br /&gt;
description= GeometryStreamGenerator.h| &lt;br /&gt;
code=&lt;br /&gt;
&amp;lt;source lang=&amp;quot;cpp&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
#pragma once&lt;br /&gt;
#include &amp;quot;StreamGenerator.h&amp;quot;&lt;br /&gt;
#include &amp;quot;CustomGeometry.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
class GeometryStreamGenerator : public StreamGenerator&lt;br /&gt;
{&lt;br /&gt;
private:&lt;br /&gt;
	std::stringstream* ss;&lt;br /&gt;
	void generate();&lt;br /&gt;
	int numVertices, numTriangleIndices;&lt;br /&gt;
	char* _stream;&lt;br /&gt;
	CustomGeometry* _geom;&lt;br /&gt;
&lt;br /&gt;
public:&lt;br /&gt;
	GeometryStreamGenerator(CustomGeometry* geom_);&lt;br /&gt;
	~GeometryStreamGenerator();&lt;br /&gt;
	const char* getStream();&lt;br /&gt;
	const std::stringstream* getStringStream() { return ss; };&lt;br /&gt;
	const int getStreamSize();&lt;br /&gt;
	const int getNumVertices();&lt;br /&gt;
	const int getNumTriangleIndices();&lt;br /&gt;
	void release();&lt;br /&gt;
};&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{CppSourceCode|&lt;br /&gt;
description= GeometryStreamGenerator.cpp| &lt;br /&gt;
code=&lt;br /&gt;
&amp;lt;source lang=&amp;quot;cpp&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;quot;GeometryStreamGenerator.h&amp;quot;&lt;br /&gt;
#include &amp;quot;time.h&amp;quot;&lt;br /&gt;
#include &amp;quot;utMath.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
GeometryStreamGenerator::GeometryStreamGenerator(CustomGeometry* geom_) : _geom(geom_)&lt;br /&gt;
{&lt;br /&gt;
	ss = new std::stringstream();&lt;br /&gt;
	generate();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
GeometryStreamGenerator::~GeometryStreamGenerator()&lt;br /&gt;
{&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void GeometryStreamGenerator::generate()&lt;br /&gt;
{&lt;br /&gt;
	numVertices = _geom-&amp;gt;getNumVertices();&lt;br /&gt;
	numTriangleIndices = _geom-&amp;gt;getNumTriangleIndices();&lt;br /&gt;
	const std::string _magicHeader = &amp;quot;H3DG&amp;quot;;&lt;br /&gt;
	const int _version = 5;&lt;br /&gt;
	const int _numJoints = 1;&lt;br /&gt;
	const float _identityMatrix[] = {	1.0f, 0.0f, 0.0f, 0.0f,  &lt;br /&gt;
										0.0f, 1.0f, 0.0f, 0.0f,  &lt;br /&gt;
										0.0f, 0.0f, 1.0f, 0.0f,  &lt;br /&gt;
										0.0f, 0.0f, 0.0f, 1.0f};&lt;br /&gt;
	const int _numVertexStreams = 3;&lt;br /&gt;
	const int _magicVertices = 0;&lt;br /&gt;
	const int _vertexStreamElementSize = 12;&lt;br /&gt;
	const float* _positions = _geom-&amp;gt;getPositions();&lt;br /&gt;
	const int _magicNormals = 1;&lt;br /&gt;
	const int _normalsStreamElementSize = 6;&lt;br /&gt;
	const float* _normals = _geom-&amp;gt;getNormals();&lt;br /&gt;
	const int _magicTextureCoords1 = 6;&lt;br /&gt;
	const int _texCoordStreamElementSize = 8;&lt;br /&gt;
	const float* _texCoords = _geom-&amp;gt;getTexCoords();&lt;br /&gt;
	const int* _triangleIndices = _geom-&amp;gt;getTriangleIndices();&lt;br /&gt;
	const int _numMorphTragets = 0;&lt;br /&gt;
	// header&lt;br /&gt;
	ss-&amp;gt;write(_magicHeader.c_str(), 4*sizeof(char));&lt;br /&gt;
	ss-&amp;gt;write((char*)&amp;amp;_version, sizeof(int));&lt;br /&gt;
	// joints (mandatory)&lt;br /&gt;
	ss-&amp;gt;write((char*)&amp;amp;_numJoints, sizeof(int));&lt;br /&gt;
	for (int i=0; i&amp;lt;16; ++i) {&lt;br /&gt;
		ss-&amp;gt;write((char*)&amp;amp;_identityMatrix[i], sizeof(float));&lt;br /&gt;
	}&lt;br /&gt;
	// vertices&lt;br /&gt;
	ss-&amp;gt;write((char*)&amp;amp;_numVertexStreams, sizeof(int));&lt;br /&gt;
	const int numVerts = _geom-&amp;gt;getNumVertices();&lt;br /&gt;
	ss-&amp;gt;write((char*)&amp;amp;numVerts, sizeof(int));&lt;br /&gt;
	ss-&amp;gt;write((char*)&amp;amp;_magicVertices, sizeof(int));&lt;br /&gt;
	ss-&amp;gt;write((char*)&amp;amp;_vertexStreamElementSize, sizeof(int));&lt;br /&gt;
	for (int i=0; i&amp;lt;_geom-&amp;gt;getNumVertices()*3; ++i) {&lt;br /&gt;
		ss-&amp;gt;write((char*)&amp;amp;_positions[i], sizeof(float));&lt;br /&gt;
	}&lt;br /&gt;
	// normals&lt;br /&gt;
	ss-&amp;gt;write((char*)&amp;amp;_magicNormals, sizeof(int));&lt;br /&gt;
	ss-&amp;gt;write((char*)&amp;amp;_normalsStreamElementSize, sizeof(int));&lt;br /&gt;
	for (int i=0; i&amp;lt;_geom-&amp;gt;getNumVertices()*3; ++i) {&lt;br /&gt;
		// do not forget to mutliply the value with 32767 and &lt;br /&gt;
		// then convert it to short before writing to the stream&lt;br /&gt;
		const short f = (short)(_normals[i]*32767);&lt;br /&gt;
		ss-&amp;gt;write((char*)&amp;amp;f, sizeof(short));&lt;br /&gt;
	}&lt;br /&gt;
	// texture coordinates&lt;br /&gt;
	ss-&amp;gt;write((char*)&amp;amp;_magicTextureCoords1, sizeof(int));&lt;br /&gt;
	ss-&amp;gt;write((char*)&amp;amp;_texCoordStreamElementSize, sizeof(int));&lt;br /&gt;
	for (int i=0; i&amp;lt;_geom-&amp;gt;getNumVertices()*2; ++i) {&lt;br /&gt;
		ss-&amp;gt;write((char*)&amp;amp;_texCoords[i], sizeof(float));&lt;br /&gt;
	}&lt;br /&gt;
	// triangle indices&lt;br /&gt;
	const int numTriangleIndices = _geom-&amp;gt;getNumTriangleIndices();&lt;br /&gt;
	ss-&amp;gt;write((char*)&amp;amp;numTriangleIndices, sizeof(int));&lt;br /&gt;
	for (int i=0; i&amp;lt;_geom-&amp;gt;getNumTriangleIndices(); ++i) {&lt;br /&gt;
		ss-&amp;gt;write((char*)&amp;amp;_triangleIndices[i], sizeof(int));&lt;br /&gt;
	}&lt;br /&gt;
	ss-&amp;gt;write((char*)&amp;amp;_numMorphTragets, sizeof(int));&lt;br /&gt;
	_stream = new char[ss-&amp;gt;tellp()];&lt;br /&gt;
	ss-&amp;gt;read(_stream, ss-&amp;gt;tellp());&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
const char* GeometryStreamGenerator::getStream()&lt;br /&gt;
{&lt;br /&gt;
	return _stream;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
const int GeometryStreamGenerator::getStreamSize() &lt;br /&gt;
{&lt;br /&gt;
	int t = (int)ss-&amp;gt;tellp();&lt;br /&gt;
	return t;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
const int GeometryStreamGenerator::getNumVertices()&lt;br /&gt;
{&lt;br /&gt;
	return numVertices;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
const int GeometryStreamGenerator::getNumTriangleIndices()&lt;br /&gt;
{&lt;br /&gt;
	return numTriangleIndices;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void GeometryStreamGenerator::release()&lt;br /&gt;
{&lt;br /&gt;
	ss-&amp;gt;flush();&lt;br /&gt;
	ss-&amp;gt;clear();&lt;br /&gt;
	delete ss;&lt;br /&gt;
	ss = 0;&lt;br /&gt;
	delete[] _stream;&lt;br /&gt;
	_stream = 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
=CustomGeometry base class=&lt;br /&gt;
&lt;br /&gt;
=Simple Square=&lt;br /&gt;
&lt;br /&gt;
=Simple Grid=&lt;br /&gt;
&lt;br /&gt;
=Usage example=&lt;/div&gt;</summary>
		<author><name>Wakko</name></author>	</entry>

	<entry>
		<id>http://horde3d.org/wiki/index.php?title=Procedurally_generated_geometry_tutorial&amp;diff=558</id>
		<title>Procedurally generated geometry tutorial</title>
		<link rel="alternate" type="text/html" href="http://horde3d.org/wiki/index.php?title=Procedurally_generated_geometry_tutorial&amp;diff=558"/>
				<updated>2009-10-26T10:35:15Z</updated>
		
		<summary type="html">&lt;p&gt;Wakko: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Due to the current changes in the Horde API this tutorial will be delayed ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Work in progress'''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
= Important notes=&lt;br /&gt;
* The code used here has been tested with Horde3D 1.0.0 beta2 and beta3 and will '''NOT''' work with the latest release (beta4)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=Overview=&lt;br /&gt;
==Basic approach==&lt;br /&gt;
To create and display a procedurally generated mesh that, instead of being loaded from a Horde3D Scene node and a geoemtry file(*.scene.xml, *.geo), will be created in-memory by some algorithm, you have to create a mesh first and then &amp;quot;fake&amp;quot; the .geo-file and the scene node itself and pass it to the engine.&lt;br /&gt;
&lt;br /&gt;
To do that you have to create your procedural geometry first. This is easy for simple shapes like single triangles, squares or triangle-strips, but will become way more difficult when we try to generate complex meshes, e.g. when we have a cloud of points in 3D space and have to describe which points make triangles, and which don't (calculating the triangle indices, texture coordinates and normals).&lt;br /&gt;
&lt;br /&gt;
When we have calculated the geometry itself we need to create a char-stream to make Horde believe the geometry has been read from a file and pass it to Horde as a geometry Resource.&lt;br /&gt;
The final step is to create a Horde3D Scene Node from our procedurally generated mesh and render it into our scene.&lt;br /&gt;
[http://musicracer.de/images/musicracer_intro.jpg &lt;br /&gt;
This is how it could look like]&lt;br /&gt;
&lt;br /&gt;
=StreamGenerator=&lt;br /&gt;
{{CppSourceCode|&lt;br /&gt;
description= StreamGenerator.h| &lt;br /&gt;
code=&lt;br /&gt;
&amp;lt;source lang=&amp;quot;cpp&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
#pragma once&lt;br /&gt;
#include &amp;lt;sstream&amp;gt;&lt;br /&gt;
#include &amp;lt;string&amp;gt;&lt;br /&gt;
#include &amp;lt;iostream&amp;gt;&lt;br /&gt;
&lt;br /&gt;
class StreamGenerator &lt;br /&gt;
{&lt;br /&gt;
public:&lt;br /&gt;
	StreamGenerator();&lt;br /&gt;
	virtual ~StreamGenerator();&lt;br /&gt;
	virtual const char* getStream() = 0;&lt;br /&gt;
	virtual const int getStreamSize() = 0;&lt;br /&gt;
};&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{CppSourceCode|&lt;br /&gt;
description= StreamGenerator.h| &lt;br /&gt;
code=&lt;br /&gt;
&amp;lt;source lang=&amp;quot;cpp&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;quot;StreamGenerator.cpp&amp;quot;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
StreamGenerator::StreamGenerator() &lt;br /&gt;
&lt;br /&gt;
{&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
StreamGenerator::~StreamGenerator()&lt;br /&gt;
&lt;br /&gt;
{&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{CppSourceCode|&lt;br /&gt;
description= GeometryStreamGenerator.h| &lt;br /&gt;
code=&lt;br /&gt;
&amp;lt;source lang=&amp;quot;cpp&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
#pragma once&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
#include &amp;quot;StreamGenerator.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
#include &amp;quot;CustomGeometry.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
class GeometryStreamGenerator : public StreamGenerator&lt;br /&gt;
&lt;br /&gt;
{&lt;br /&gt;
&lt;br /&gt;
private:&lt;br /&gt;
&lt;br /&gt;
	std::stringstream* ss;&lt;br /&gt;
&lt;br /&gt;
	void generate();&lt;br /&gt;
&lt;br /&gt;
	int numVertices, numTriangleIndices;&lt;br /&gt;
&lt;br /&gt;
	char* _stream;&lt;br /&gt;
&lt;br /&gt;
	CustomGeometry* _geom;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
public:&lt;br /&gt;
&lt;br /&gt;
	GeometryStreamGenerator(CustomGeometry* geom_);&lt;br /&gt;
&lt;br /&gt;
	~GeometryStreamGenerator();&lt;br /&gt;
&lt;br /&gt;
	const char* getStream();&lt;br /&gt;
&lt;br /&gt;
	const std::stringstream* getStringStream() { return ss; };&lt;br /&gt;
&lt;br /&gt;
	const int getStreamSize();&lt;br /&gt;
&lt;br /&gt;
	const int getNumVertices();&lt;br /&gt;
&lt;br /&gt;
	const int getNumTriangleIndices();&lt;br /&gt;
&lt;br /&gt;
	void release();&lt;br /&gt;
&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{CppSourceCode|&lt;br /&gt;
description= GeometryStreamGenerator.cpp| &lt;br /&gt;
code=&lt;br /&gt;
&amp;lt;source lang=&amp;quot;cpp&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;quot;GeometryStreamGenerator.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
#include &amp;quot;time.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
#include &amp;quot;utMath.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
GeometryStreamGenerator::GeometryStreamGenerator(CustomGeometry* geom_) : _geom(geom_)&lt;br /&gt;
&lt;br /&gt;
{&lt;br /&gt;
&lt;br /&gt;
	ss = new std::stringstream();&lt;br /&gt;
&lt;br /&gt;
	generate();&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
GeometryStreamGenerator::~GeometryStreamGenerator()&lt;br /&gt;
&lt;br /&gt;
{&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
void GeometryStreamGenerator::generate()&lt;br /&gt;
&lt;br /&gt;
{&lt;br /&gt;
&lt;br /&gt;
	numVertices = _geom-&amp;gt;getNumVertices();&lt;br /&gt;
&lt;br /&gt;
	numTriangleIndices = _geom-&amp;gt;getNumTriangleIndices();&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
	const std::string _magicHeader = &amp;quot;H3DG&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
	const int _version = 5;&lt;br /&gt;
&lt;br /&gt;
	const int _numJoints = 1;&lt;br /&gt;
&lt;br /&gt;
	const float _identityMatrix[] = {	1.0f, 0.0f, 0.0f, 0.0f,  &lt;br /&gt;
&lt;br /&gt;
										0.0f, 1.0f, 0.0f, 0.0f,  &lt;br /&gt;
&lt;br /&gt;
										0.0f, 0.0f, 1.0f, 0.0f,  &lt;br /&gt;
&lt;br /&gt;
										0.0f, 0.0f, 0.0f, 1.0f};&lt;br /&gt;
&lt;br /&gt;
	const int _numVertexStreams = 3;&lt;br /&gt;
&lt;br /&gt;
	const int _magicVertices = 0;&lt;br /&gt;
&lt;br /&gt;
	const int _vertexStreamElementSize = 12;&lt;br /&gt;
&lt;br /&gt;
	const float* _positions = _geom-&amp;gt;getPositions();&lt;br /&gt;
&lt;br /&gt;
	const int _magicNormals = 1;&lt;br /&gt;
&lt;br /&gt;
	const int _normalsStreamElementSize = 6;&lt;br /&gt;
&lt;br /&gt;
	const float* _normals = _geom-&amp;gt;getNormals();&lt;br /&gt;
&lt;br /&gt;
	const int _magicTextureCoords1 = 6;&lt;br /&gt;
&lt;br /&gt;
	const int _texCoordStreamElementSize = 8;&lt;br /&gt;
&lt;br /&gt;
	const float* _texCoords = _geom-&amp;gt;getTexCoords();&lt;br /&gt;
&lt;br /&gt;
	const int* _triangleIndices = _geom-&amp;gt;getTriangleIndices();&lt;br /&gt;
&lt;br /&gt;
	const int _numMorphTragets = 0;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
	// header&lt;br /&gt;
&lt;br /&gt;
	ss-&amp;gt;write(_magicHeader.c_str(), 4*sizeof(char));&lt;br /&gt;
&lt;br /&gt;
	ss-&amp;gt;write((char*)&amp;amp;_version, sizeof(int));&lt;br /&gt;
&lt;br /&gt;
	// joints (mandatory)&lt;br /&gt;
&lt;br /&gt;
	ss-&amp;gt;write((char*)&amp;amp;_numJoints, sizeof(int));&lt;br /&gt;
&lt;br /&gt;
	for (int i=0; i&amp;lt;16; ++i) {&lt;br /&gt;
&lt;br /&gt;
		ss-&amp;gt;write((char*)&amp;amp;_identityMatrix[i], sizeof(float));&lt;br /&gt;
&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	// vertices&lt;br /&gt;
&lt;br /&gt;
	ss-&amp;gt;write((char*)&amp;amp;_numVertexStreams, sizeof(int));&lt;br /&gt;
&lt;br /&gt;
	const int numVerts = _geom-&amp;gt;getNumVertices();&lt;br /&gt;
&lt;br /&gt;
	ss-&amp;gt;write((char*)&amp;amp;numVerts, sizeof(int));&lt;br /&gt;
&lt;br /&gt;
	ss-&amp;gt;write((char*)&amp;amp;_magicVertices, sizeof(int));&lt;br /&gt;
&lt;br /&gt;
	ss-&amp;gt;write((char*)&amp;amp;_vertexStreamElementSize, sizeof(int));&lt;br /&gt;
&lt;br /&gt;
	for (int i=0; i&amp;lt;_geom-&amp;gt;getNumVertices()*3; ++i) {&lt;br /&gt;
&lt;br /&gt;
		ss-&amp;gt;write((char*)&amp;amp;_positions[i], sizeof(float));&lt;br /&gt;
&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	// normals&lt;br /&gt;
&lt;br /&gt;
	ss-&amp;gt;write((char*)&amp;amp;_magicNormals, sizeof(int));&lt;br /&gt;
&lt;br /&gt;
	ss-&amp;gt;write((char*)&amp;amp;_normalsStreamElementSize, sizeof(int));&lt;br /&gt;
&lt;br /&gt;
	for (int i=0; i&amp;lt;_geom-&amp;gt;getNumVertices()*3; ++i) {&lt;br /&gt;
&lt;br /&gt;
		// do not forget to mutliply the value with 32767 and &lt;br /&gt;
&lt;br /&gt;
		// then convert it to short before writing to the stream&lt;br /&gt;
&lt;br /&gt;
		const short f = (short)(_normals[i]*32767);&lt;br /&gt;
&lt;br /&gt;
		ss-&amp;gt;write((char*)&amp;amp;f, sizeof(short));&lt;br /&gt;
&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	// texture coordinates&lt;br /&gt;
&lt;br /&gt;
	ss-&amp;gt;write((char*)&amp;amp;_magicTextureCoords1, sizeof(int));&lt;br /&gt;
&lt;br /&gt;
	ss-&amp;gt;write((char*)&amp;amp;_texCoordStreamElementSize, sizeof(int));&lt;br /&gt;
&lt;br /&gt;
	for (int i=0; i&amp;lt;_geom-&amp;gt;getNumVertices()*2; ++i) {&lt;br /&gt;
&lt;br /&gt;
		ss-&amp;gt;write((char*)&amp;amp;_texCoords[i], sizeof(float));&lt;br /&gt;
&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	// triangle indices&lt;br /&gt;
&lt;br /&gt;
	const int numTriangleIndices = _geom-&amp;gt;getNumTriangleIndices();&lt;br /&gt;
&lt;br /&gt;
	ss-&amp;gt;write((char*)&amp;amp;numTriangleIndices, sizeof(int));&lt;br /&gt;
&lt;br /&gt;
	for (int i=0; i&amp;lt;_geom-&amp;gt;getNumTriangleIndices(); ++i) {&lt;br /&gt;
&lt;br /&gt;
		ss-&amp;gt;write((char*)&amp;amp;_triangleIndices[i], sizeof(int));&lt;br /&gt;
&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	ss-&amp;gt;write((char*)&amp;amp;_numMorphTragets, sizeof(int));&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
	_stream = new char[ss-&amp;gt;tellp()];&lt;br /&gt;
&lt;br /&gt;
	ss-&amp;gt;read(_stream, ss-&amp;gt;tellp());&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
const char* GeometryStreamGenerator::getStream()&lt;br /&gt;
&lt;br /&gt;
{&lt;br /&gt;
&lt;br /&gt;
	return _stream;&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
const int GeometryStreamGenerator::getStreamSize() &lt;br /&gt;
&lt;br /&gt;
{&lt;br /&gt;
&lt;br /&gt;
	int t = (int)ss-&amp;gt;tellp();&lt;br /&gt;
&lt;br /&gt;
	return t;&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
const int GeometryStreamGenerator::getNumVertices()&lt;br /&gt;
&lt;br /&gt;
{&lt;br /&gt;
&lt;br /&gt;
	return numVertices;&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
const int GeometryStreamGenerator::getNumTriangleIndices()&lt;br /&gt;
&lt;br /&gt;
{&lt;br /&gt;
&lt;br /&gt;
	return numTriangleIndices;&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
void GeometryStreamGenerator::release()&lt;br /&gt;
&lt;br /&gt;
{&lt;br /&gt;
&lt;br /&gt;
	ss-&amp;gt;flush();&lt;br /&gt;
&lt;br /&gt;
	ss-&amp;gt;clear();&lt;br /&gt;
&lt;br /&gt;
	delete ss;&lt;br /&gt;
&lt;br /&gt;
	ss = 0;&lt;br /&gt;
&lt;br /&gt;
	delete[] _stream;&lt;br /&gt;
&lt;br /&gt;
	_stream = 0;&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=CustomGeometry base class=&lt;br /&gt;
&lt;br /&gt;
=Simple Square=&lt;br /&gt;
&lt;br /&gt;
=Simple Grid=&lt;br /&gt;
&lt;br /&gt;
=Usage example=&lt;/div&gt;</summary>
		<author><name>Wakko</name></author>	</entry>

	<entry>
		<id>http://horde3d.org/wiki/index.php?title=Procedurally_generated_geometry_tutorial&amp;diff=557</id>
		<title>Procedurally generated geometry tutorial</title>
		<link rel="alternate" type="text/html" href="http://horde3d.org/wiki/index.php?title=Procedurally_generated_geometry_tutorial&amp;diff=557"/>
				<updated>2009-10-26T10:32:39Z</updated>
		
		<summary type="html">&lt;p&gt;Wakko: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
== Due to the current changes in the Horde API this tutorial will be delayed ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Work in progress'''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
= Important notes=&lt;br /&gt;
* The code used here has been tested with Horde3D 1.0.0 beta2 and beta3 and will '''NOT''' work with the latest release (beta4)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=Overview=&lt;br /&gt;
==Basic approach==&lt;br /&gt;
To create and display a procedurally generated mesh that, instead of being loaded from a Horde3D Scene node and a geoemtry file(*.scene.xml, *.geo), will be created in-memory by some algorithm, you have to create a mesh first and then &amp;quot;fake&amp;quot; the .geo-file and the scene node itself and pass it to the engine.&lt;br /&gt;
&lt;br /&gt;
To do that you have to create your procedural geometry first. This is easy for simple shapes like single triangles, squares or triangle-strips, but will become way more difficult when we try to generate complex meshes, e.g. when we have a cloud of points in 3D space and have to describe which points make triangles, and which don't (calculating the triangle indices, texture coordinates and normals).&lt;br /&gt;
&lt;br /&gt;
When we have calculated the geometry itself we need to create a char-stream to make Horde believe the geometry has been read from a file and pass it to Horde as a geometry Resource.&lt;br /&gt;
The final step is to create a Horde3D Scene Node from our procedurally generated mesh and render it into our scene.&lt;br /&gt;
[http://musicracer.de/images/musicracer_intro.jpg &lt;br /&gt;
This is how it could look like]&lt;br /&gt;
&lt;br /&gt;
=StreamGenerator=&lt;br /&gt;
{{CppSourceCode|&lt;br /&gt;
description= StreamGenerator.h| &lt;br /&gt;
code=&lt;br /&gt;
&amp;lt;source lang=&amp;quot;cpp&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
#pragma once&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
#include &amp;lt;sstream&amp;gt;&lt;br /&gt;
&lt;br /&gt;
#include &amp;lt;string&amp;gt;&lt;br /&gt;
&lt;br /&gt;
#include &amp;lt;iostream&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
class StreamGenerator &lt;br /&gt;
&lt;br /&gt;
{&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
public:&lt;br /&gt;
&lt;br /&gt;
	StreamGenerator();&lt;br /&gt;
&lt;br /&gt;
	virtual ~StreamGenerator();&lt;br /&gt;
&lt;br /&gt;
	virtual const char* getStream() = 0;&lt;br /&gt;
&lt;br /&gt;
	virtual const int getStreamSize() = 0;&lt;br /&gt;
&lt;br /&gt;
};&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
=CustomGeometry base class=&lt;br /&gt;
&lt;br /&gt;
=Simple Square=&lt;br /&gt;
&lt;br /&gt;
=Simple Grid=&lt;br /&gt;
&lt;br /&gt;
=Usage example=&lt;/div&gt;</summary>
		<author><name>Wakko</name></author>	</entry>

	<entry>
		<id>http://horde3d.org/wiki/index.php?title=Procedurally_generated_geometry_tutorial&amp;diff=545</id>
		<title>Procedurally generated geometry tutorial</title>
		<link rel="alternate" type="text/html" href="http://horde3d.org/wiki/index.php?title=Procedurally_generated_geometry_tutorial&amp;diff=545"/>
				<updated>2009-08-27T19:23:38Z</updated>
		
		<summary type="html">&lt;p&gt;Wakko: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;'''Work in progress'''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
= Important notes=&lt;br /&gt;
* The code used here has been tested with Horde3D 1.0.0 beta2 and beta3 and will '''NOT''' work with the latest release (beta4)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=Overview=&lt;br /&gt;
==Basic approach==&lt;br /&gt;
To create and display a procedurally generated mesh that, instead of being loaded from a Horde3D Scene node and a geoemtry file(*.scene.xml, *.geo), will be created in-memory by some algorithm, you have to create a mesh first and then &amp;quot;fake&amp;quot; the .geo-file and the scene node itself and pass it to the engine.&lt;br /&gt;
&lt;br /&gt;
To do that you have to create your procedural geometry first. This is easy for simple shapes like single triangles, squares or triangle-strips, but will become way more difficult when we try to generate complex meshes, e.g. when we have a cloud of points in 3D space and have to describe which points make triangles, and which don't (calculating the triangle indices, texture coordinates and normals).&lt;br /&gt;
&lt;br /&gt;
When we have calculated the geometry itself we need to create a char-stream to make Horde believe the geometry has been read from a file and pass it to Horde as a geometry Resource.&lt;br /&gt;
The final step is to create a Horde3D Scene Node from our procedurally generated mesh and render it into our scene.&lt;br /&gt;
[http://musicracer.de/images/musicracer_intro.jpg &lt;br /&gt;
This is how it could look like]&lt;br /&gt;
&lt;br /&gt;
=StreamGenerator=&lt;br /&gt;
&lt;br /&gt;
=CustomGeometry base class=&lt;br /&gt;
&lt;br /&gt;
=Simple Square=&lt;br /&gt;
&lt;br /&gt;
=Simple Grid=&lt;br /&gt;
&lt;br /&gt;
=Usage example=&lt;/div&gt;</summary>
		<author><name>Wakko</name></author>	</entry>

	<entry>
		<id>http://horde3d.org/wiki/index.php?title=Procedurally_generated_geometry_tutorial&amp;diff=544</id>
		<title>Procedurally generated geometry tutorial</title>
		<link rel="alternate" type="text/html" href="http://horde3d.org/wiki/index.php?title=Procedurally_generated_geometry_tutorial&amp;diff=544"/>
				<updated>2009-08-27T19:22:57Z</updated>
		
		<summary type="html">&lt;p&gt;Wakko: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;'''Work in progress'''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
= Important notes=&lt;br /&gt;
* The code used here has been tested with Horde3D 1.0.0 beta2 and beta3 and will '''NOT''' work with the latest release (beta4)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=Overview=&lt;br /&gt;
==Basic approach==&lt;br /&gt;
To create and display a procedurally generated mesh that, instead of being loaded from a Horde3D Scene node and a geoemtry file(*.scene.xml, *.geo), will be created in-memory by some algorithm, you have to create a mesh first and then &amp;quot;fake&amp;quot; the .geo-file and the scene node itself and pass it to the engine.&lt;br /&gt;
&lt;br /&gt;
To do that you have to create your procedural geometry first. This is easy for simple shapes like single triangles, squares or triangle-strips, but will become way more difficult when we try to generate complex meshes, e.g. when we have a cloud of points in 3D space and have to describe which points make triangles, and which don't (calculating the triangle indices, texture coordinates and normals).&lt;br /&gt;
&lt;br /&gt;
When we have calculated the geometry itself we need to create a char-stream to make Horde believe the geometry has been read from a file and pass it to Horde as a geometry Resource.&lt;br /&gt;
The final step is to create a Horde3D Scene Node from our procedurally generated mesh and render it into our scene.&lt;br /&gt;
[http://musicracer.de/images/musicracer_intro.jpg &lt;br /&gt;
&lt;br /&gt;
This is how it could look like]&lt;br /&gt;
&lt;br /&gt;
=StreamGenerator=&lt;br /&gt;
&lt;br /&gt;
=CustomGeometry base class=&lt;br /&gt;
&lt;br /&gt;
=Simple Square=&lt;br /&gt;
&lt;br /&gt;
=Simple Grid=&lt;br /&gt;
&lt;br /&gt;
=Usage example=&lt;/div&gt;</summary>
		<author><name>Wakko</name></author>	</entry>

	<entry>
		<id>http://horde3d.org/wiki/index.php?title=Procedurally_generated_geometry_tutorial&amp;diff=543</id>
		<title>Procedurally generated geometry tutorial</title>
		<link rel="alternate" type="text/html" href="http://horde3d.org/wiki/index.php?title=Procedurally_generated_geometry_tutorial&amp;diff=543"/>
				<updated>2009-08-27T19:22:37Z</updated>
		
		<summary type="html">&lt;p&gt;Wakko: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;'''Work in progress'''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
= Important notes=&lt;br /&gt;
* The code used here has been tested with Horde3D 1.0.0 beta2 and beta3 and will '''NOT''' work with the latest release (beta4)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=Overview=&lt;br /&gt;
==Basic approach==&lt;br /&gt;
To create and display a procedurally generated mesh that, instead of being loaded from a Horde3D Scene node and a geoemtry file(*.scene.xml, *.geo), will be created in-memory by some algorithm, you have to create a mesh first and then &amp;quot;fake&amp;quot; the .geo-file and the scene node itself and pass it to the engine.&lt;br /&gt;
&lt;br /&gt;
To do that you have to create your procedural geometry first. This is easy for simple shapes like single triangles, squares or triangle-strips, but will become way more difficult when we try to generate complex meshes, e.g. when we have a cloud of points in 3D space and have to describe which points make triangles, and which don't (calculating the triangle indices, texture coordinates and normals).&lt;br /&gt;
&lt;br /&gt;
When we have calculated the geometry itself we need to create a char-stream to make Horde believe the geometry has been read from a file and pass it to Horde as a geometry Resource.&lt;br /&gt;
The final step is to create a Horde3D Scene Node from our procedurally generated mesh and render it into our scene.&lt;br /&gt;
[http://musicracer.de/images/musicracer_intro.jpg This is how it could look]&lt;br /&gt;
&lt;br /&gt;
=StreamGenerator=&lt;br /&gt;
&lt;br /&gt;
=CustomGeometry base class=&lt;br /&gt;
&lt;br /&gt;
=Simple Square=&lt;br /&gt;
&lt;br /&gt;
=Simple Grid=&lt;br /&gt;
&lt;br /&gt;
=Usage example=&lt;/div&gt;</summary>
		<author><name>Wakko</name></author>	</entry>

	<entry>
		<id>http://horde3d.org/wiki/index.php?title=Procedurally_generated_geometry_tutorial&amp;diff=542</id>
		<title>Procedurally generated geometry tutorial</title>
		<link rel="alternate" type="text/html" href="http://horde3d.org/wiki/index.php?title=Procedurally_generated_geometry_tutorial&amp;diff=542"/>
				<updated>2009-08-27T19:21:25Z</updated>
		
		<summary type="html">&lt;p&gt;Wakko: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;'''Work in progress'''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
= Important notes=&lt;br /&gt;
* The code used here has been tested with Horde3D 1.0.0 beta2 and beta3 and will '''NOT''' work with the latest release (beta4)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=Overview=&lt;br /&gt;
==Basic approach==&lt;br /&gt;
To create and display a procedurally generated mesh that, instead of being loaded from a Horde3D Scene node and a geoemtry file(*.scene.xml, *.geo), will be created in-memory by some algorithm, you have to create a mesh first and then &amp;quot;fake&amp;quot; the .geo-file and the scene node itself and pass it to the engine.&lt;br /&gt;
&lt;br /&gt;
To do that you have to create your procedural geometry first. This is easy for simple shapes like single triangles, squares or triangle-strips, but will become way more difficult when we try to generate complex meshes, e.g. when we have a cloud of points in 3D space and have to describe which points make triangles, and which don't (calculating the triangle indices, texture coordinates and normals).&lt;br /&gt;
&lt;br /&gt;
When we have calculated the geometry itself we need to create a char-stream to make Horde believe the geometry has been read from a file and pass it to Horde as a geometry Resource.&lt;br /&gt;
The final step is to create a Horde3D Scene Node from our procedurally generated mesh and render it into our scene.&lt;br /&gt;
[http://musicracer.de/images/musicracer_intro.jpg]&lt;br /&gt;
[[Media:http://musicracer.de/images/musicracer_intro.jpg]]&lt;br /&gt;
&lt;br /&gt;
=StreamGenerator=&lt;br /&gt;
&lt;br /&gt;
=CustomGeometry base class=&lt;br /&gt;
&lt;br /&gt;
=Simple Square=&lt;br /&gt;
&lt;br /&gt;
=Simple Grid=&lt;br /&gt;
&lt;br /&gt;
=Usage example=&lt;/div&gt;</summary>
		<author><name>Wakko</name></author>	</entry>

	<entry>
		<id>http://horde3d.org/wiki/index.php?title=Procedurally_generated_geometry_tutorial&amp;diff=541</id>
		<title>Procedurally generated geometry tutorial</title>
		<link rel="alternate" type="text/html" href="http://horde3d.org/wiki/index.php?title=Procedurally_generated_geometry_tutorial&amp;diff=541"/>
				<updated>2009-08-27T19:20:33Z</updated>
		
		<summary type="html">&lt;p&gt;Wakko: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;'''Work in progress'''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
= Important notes=&lt;br /&gt;
* The code used here has been tested with Horde3D 1.0.0 beta2 and beta3 and will '''NOT''' work with the latest release (beta4)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=Overview=&lt;br /&gt;
==Basic approach==&lt;br /&gt;
To create and display a procedurally generated mesh that, instead of being loaded from a Horde3D Scene node and a geoemtry file(*.scene.xml, *.geo), will be created in-memory by some algorithm, you have to create a mesh first and then &amp;quot;fake&amp;quot; the .geo-file and the scene node itself and pass it to the engine.&lt;br /&gt;
&lt;br /&gt;
To do that you have to create your procedural geometry first. This is easy for simple shapes like single triangles, squares or triangle-strips, but will become way more difficult when we try to generate complex meshes, e.g. when we have a cloud of points in 3D space and have to describe which points make triangles, and which don't (calculating the triangle indices, texture coordinates and normals).&lt;br /&gt;
&lt;br /&gt;
When we have calculated the geometry itself we need to create a char-stream to make Horde believe the geometry has been read from a file and pass it to Horde as a geometry Resource.&lt;br /&gt;
The final step is to create a Horde3D Scene Node from our procedurally generated mesh and render it into our scene.&lt;br /&gt;
[http://musicracer.de/images/musicracer_intro.jpg]&lt;br /&gt;
&lt;br /&gt;
=StreamGenerator=&lt;br /&gt;
&lt;br /&gt;
=CustomGeometry base class=&lt;br /&gt;
&lt;br /&gt;
=Simple Square=&lt;br /&gt;
&lt;br /&gt;
=Simple Grid=&lt;br /&gt;
&lt;br /&gt;
=Usage example=&lt;/div&gt;</summary>
		<author><name>Wakko</name></author>	</entry>

	<entry>
		<id>http://horde3d.org/wiki/index.php?title=Procedurally_generated_geometry_tutorial&amp;diff=540</id>
		<title>Procedurally generated geometry tutorial</title>
		<link rel="alternate" type="text/html" href="http://horde3d.org/wiki/index.php?title=Procedurally_generated_geometry_tutorial&amp;diff=540"/>
				<updated>2009-08-27T19:20:08Z</updated>
		
		<summary type="html">&lt;p&gt;Wakko: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;'''Work in progress'''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
= Important notes=&lt;br /&gt;
* The code used here has been tested with Horde3D 1.0.0 beta2 and beta3 and will '''NOT''' work with the latest release (beta4)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=Overview=&lt;br /&gt;
==Basic approach==&lt;br /&gt;
To create and display a procedurally generated mesh that, instead of being loaded from a Horde3D Scene node and a geoemtry file(*.scene.xml, *.geo), will be created in-memory by some algorithm, you have to create a mesh first and then &amp;quot;fake&amp;quot; the .geo-file and the scene node itself and pass it to the engine.&lt;br /&gt;
&lt;br /&gt;
To do that you have to create your procedural geometry first. This is easy for simple shapes like single triangles, squares or triangle-strips, but will become way more difficult when we try to generate complex meshes, e.g. when we have a cloud of points in 3D space and have to describe which points make triangles, and which don't (calculating the triangle indices, texture coordinates and normals).&lt;br /&gt;
&lt;br /&gt;
When we have calculated the geometry itself we need to create a char-stream to make Horde believe the geometry has been read from a file and pass it to Horde as a geometry Resource.&lt;br /&gt;
The final step is to create a Horde3D Scene Node from our procedurally generated mesh and render it into our scene.&lt;br /&gt;
[[Image:http://musicracer.de/images/musicracer_intro.jpg]]&lt;br /&gt;
&lt;br /&gt;
=StreamGenerator=&lt;br /&gt;
&lt;br /&gt;
=CustomGeometry base class=&lt;br /&gt;
&lt;br /&gt;
=Simple Square=&lt;br /&gt;
&lt;br /&gt;
=Simple Grid=&lt;br /&gt;
&lt;br /&gt;
=Usage example=&lt;/div&gt;</summary>
		<author><name>Wakko</name></author>	</entry>

	<entry>
		<id>http://horde3d.org/wiki/index.php?title=Procedurally_generated_geometry_tutorial&amp;diff=539</id>
		<title>Procedurally generated geometry tutorial</title>
		<link rel="alternate" type="text/html" href="http://horde3d.org/wiki/index.php?title=Procedurally_generated_geometry_tutorial&amp;diff=539"/>
				<updated>2009-08-27T19:16:57Z</updated>
		
		<summary type="html">&lt;p&gt;Wakko: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;'''Work in progress'''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
= Important notes=&lt;br /&gt;
* The code used here has been tested with Horde3D 1.0.0 beta2 and beta3 and will '''NOT''' work with the latest release (beta4)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=Overview=&lt;br /&gt;
==Basic approach==&lt;br /&gt;
To create and display a procedurally generated mesh that, instead of being loaded from a Horde3D Scene node and a geoemtry file(*.scene.xml, *.geo), will be created in-memory by some algorithm, you have to create a mesh first and then &amp;quot;fake&amp;quot; the .geo-file and the scene node itself and pass it to the engine.&lt;br /&gt;
&lt;br /&gt;
To do that you have to create your procedural geometry first. This is easy for simple shapes like single triangles, squares or triangle-strips, but will become way more difficult when we try to generate complex meshes, e.g. when we have a cloud of points in 3D space and have to describe which points make triangles, and which don't (calculating the triangle indices, texture coordinates and normals).&lt;br /&gt;
&lt;br /&gt;
When we have calculated the geometry itself we need to create a char-stream to make Horde believe the geometry has been read from a file and pass it to Horde as a geometry Resource.&lt;br /&gt;
The final step is to create a Horde3D Scene Node from our procedurally generated mesh and render it into our scene.&lt;br /&gt;
&lt;br /&gt;
=StreamGenerator=&lt;br /&gt;
&lt;br /&gt;
=CustomGeometry base class=&lt;br /&gt;
&lt;br /&gt;
=Simple Square=&lt;br /&gt;
&lt;br /&gt;
=Simple Grid=&lt;br /&gt;
&lt;br /&gt;
=Usage example=&lt;/div&gt;</summary>
		<author><name>Wakko</name></author>	</entry>

	<entry>
		<id>http://horde3d.org/wiki/index.php?title=Procedurally_generated_geometry_tutorial&amp;diff=538</id>
		<title>Procedurally generated geometry tutorial</title>
		<link rel="alternate" type="text/html" href="http://horde3d.org/wiki/index.php?title=Procedurally_generated_geometry_tutorial&amp;diff=538"/>
				<updated>2009-08-27T19:16:41Z</updated>
		
		<summary type="html">&lt;p&gt;Wakko: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
'''Work in progress'''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
= Important notes=&lt;br /&gt;
* The code used here has been tested with Horde3D 1.0.0 beta2 and beta3 and will '''NOT''' work with the latest release (beta4)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=Overview=&lt;br /&gt;
==Basic approach==&lt;br /&gt;
To create and display a procedurally generated mesh that, instead of being loaded from a Horde3D Scene node and a geoemtry file(*.scene.xml, *.geo), will be created in-memory by some algorithm, you have to create a mesh first and then &amp;quot;fake&amp;quot; the .geo-file and the scene node itself and pass it to the engine.&lt;br /&gt;
To do that you have to create your procedural geometry first. This is easy for simple shapes like single triangles, squares or triangle-strips, but will become way more difficult when we try to generate complex meshes, e.g. when we have a cloud of points in 3D space and have to describe which points make triangles, and which don't (calculating the triangle indices, texture coordinates and normals).&lt;br /&gt;
When we have calculated the geometry itself we need to create a char-stream to make Horde believe the geometry has been read from a file and pass it to Horde as a geometry Resource.&lt;br /&gt;
The final step is to create a Horde3D Scene Node from our procedurally generated mesh and render it into our scene.&lt;br /&gt;
&lt;br /&gt;
=StreamGenerator=&lt;br /&gt;
&lt;br /&gt;
=CustomGeometry base class=&lt;br /&gt;
&lt;br /&gt;
=Simple Square=&lt;br /&gt;
&lt;br /&gt;
=Simple Grid=&lt;br /&gt;
&lt;br /&gt;
=Usage example=&lt;/div&gt;</summary>
		<author><name>Wakko</name></author>	</entry>

	<entry>
		<id>http://horde3d.org/wiki/index.php?title=Procedurally_generated_geometry_tutorial&amp;diff=537</id>
		<title>Procedurally generated geometry tutorial</title>
		<link rel="alternate" type="text/html" href="http://horde3d.org/wiki/index.php?title=Procedurally_generated_geometry_tutorial&amp;diff=537"/>
				<updated>2009-08-27T19:16:08Z</updated>
		
		<summary type="html">&lt;p&gt;Wakko: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
&lt;br /&gt;
'''Work in progress'''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
= Important notes=&lt;br /&gt;
* The code used here has been tested with Horde3D 1.0.0 beta2 and beta3 and will '''NOT''' work with the latest release (beta4)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=Overview=&lt;br /&gt;
==Basic approach==&lt;br /&gt;
To create and display a procedurally generated mesh that, instead of being loaded from a Horde3D Scene node and a geoemtry file(*.scene.xml, *.geo), will be created in-memory by some algorithm you have to create a mesh first and then &amp;quot;fake&amp;quot; the .geo-file and the scene node itself and pass it to the engine.&lt;br /&gt;
To do that you have to create your procedural geometry first. This is easy for simple shapes like single triangles, squares or triangle-strips, but will become way more difficult when we try to generate complex meshes, e.g. when we have a cloud of points in 3D space and have to describe which points make triangles, and which don't (calculating the triangle indices, texture coordinates and normals).&lt;br /&gt;
When we have calculated the geometry itself we need to create a char-stream to make Horde believe the geometry has been read from a file and pass it to Horde as a geometry Resource.&lt;br /&gt;
The final step is to create a Horde3D Scene Node from our procedurally generated mesh and render it into our scene.&lt;br /&gt;
&lt;br /&gt;
=StreamGenerator=&lt;br /&gt;
&lt;br /&gt;
=CustomGeometry base class=&lt;br /&gt;
&lt;br /&gt;
=Simple Square=&lt;br /&gt;
&lt;br /&gt;
=Simple Grid=&lt;br /&gt;
&lt;br /&gt;
=Usage example=&lt;/div&gt;</summary>
		<author><name>Wakko</name></author>	</entry>

	<entry>
		<id>http://horde3d.org/wiki/index.php?title=Procedurally_generated_geometry_tutorial&amp;diff=534</id>
		<title>Procedurally generated geometry tutorial</title>
		<link rel="alternate" type="text/html" href="http://horde3d.org/wiki/index.php?title=Procedurally_generated_geometry_tutorial&amp;diff=534"/>
				<updated>2009-08-27T18:58:57Z</updated>
		
		<summary type="html">&lt;p&gt;Wakko: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;'''Work in progress'''&lt;br /&gt;
= Important notes=&lt;br /&gt;
* The code used here has been tested with Horde3D 1.0.0 beta2 and beta3 and will '''NOT''' work with the latest release (beta4)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=Overview=&lt;br /&gt;
==The problem==&lt;br /&gt;
You want to create and display a procedurally generated mesh that, instead of being loaded from a Horde3D Scene node and a geoemtry file(*.scene.xml, *.geo), will be created in-memory by some algorithm. &lt;br /&gt;
==Basic approach==&lt;br /&gt;
To do that you have to create a mesh first and then &amp;quot;fake&amp;quot; the .geo-file and the scene node itself and pass it to the engine. &lt;br /&gt;
&lt;br /&gt;
=StreamGenerator=&lt;br /&gt;
&lt;br /&gt;
=CustomGeometry base class=&lt;br /&gt;
&lt;br /&gt;
=Simple Square=&lt;br /&gt;
&lt;br /&gt;
=Simple Grid=&lt;br /&gt;
&lt;br /&gt;
=Usage example=&lt;/div&gt;</summary>
		<author><name>Wakko</name></author>	</entry>

	<entry>
		<id>http://horde3d.org/wiki/index.php?title=Procedurally_generated_geometry_tutorial&amp;diff=533</id>
		<title>Procedurally generated geometry tutorial</title>
		<link rel="alternate" type="text/html" href="http://horde3d.org/wiki/index.php?title=Procedurally_generated_geometry_tutorial&amp;diff=533"/>
				<updated>2009-08-27T18:46:38Z</updated>
		
		<summary type="html">&lt;p&gt;Wakko: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;'''Work in progress'''&lt;br /&gt;
= Important notes=&lt;br /&gt;
* The code used here has been tested with Horde3D 1.0.0 beta2 and beta3 and will '''NOT''' work with the latest release (beta4)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=Overview=&lt;br /&gt;
&lt;br /&gt;
=StreamGenerator=&lt;br /&gt;
&lt;br /&gt;
=CustomGeometry base class=&lt;br /&gt;
&lt;br /&gt;
=Simple Square=&lt;br /&gt;
&lt;br /&gt;
=Simple Grid=&lt;br /&gt;
&lt;br /&gt;
=Usage example=&lt;/div&gt;</summary>
		<author><name>Wakko</name></author>	</entry>

	<entry>
		<id>http://horde3d.org/wiki/index.php?title=Procedurally_generated_geometry_tutorial&amp;diff=532</id>
		<title>Procedurally generated geometry tutorial</title>
		<link rel="alternate" type="text/html" href="http://horde3d.org/wiki/index.php?title=Procedurally_generated_geometry_tutorial&amp;diff=532"/>
				<updated>2009-08-27T18:45:56Z</updated>
		
		<summary type="html">&lt;p&gt;Wakko: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;### Work in progress ###&lt;br /&gt;
&lt;br /&gt;
= Important notes=&lt;br /&gt;
* The code used here has been tested with Horde3D 1.0.0 beta2 and beta3 and will '''NOT''' work with the latest release (beta4)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=Overview=&lt;br /&gt;
&lt;br /&gt;
=StreamGenerator=&lt;br /&gt;
&lt;br /&gt;
=CustomGeometry base class=&lt;br /&gt;
&lt;br /&gt;
=Simple Square=&lt;br /&gt;
&lt;br /&gt;
=Simple Grid=&lt;br /&gt;
&lt;br /&gt;
=Usage example=&lt;/div&gt;</summary>
		<author><name>Wakko</name></author>	</entry>

	<entry>
		<id>http://horde3d.org/wiki/index.php?title=Procedurally_generated_geometry_tutorial&amp;diff=530</id>
		<title>Procedurally generated geometry tutorial</title>
		<link rel="alternate" type="text/html" href="http://horde3d.org/wiki/index.php?title=Procedurally_generated_geometry_tutorial&amp;diff=530"/>
				<updated>2009-08-27T18:39:03Z</updated>
		
		<summary type="html">&lt;p&gt;Wakko: New page: ### Work in progress ###  =1. Overview=  =2. StreamGenerator=  =3. CustomGeometry base class=  =4. Simple Square=  =5. Simple Grid=&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;### Work in progress ###&lt;br /&gt;
&lt;br /&gt;
=1. Overview=&lt;br /&gt;
&lt;br /&gt;
=2. StreamGenerator=&lt;br /&gt;
&lt;br /&gt;
=3. CustomGeometry base class=&lt;br /&gt;
&lt;br /&gt;
=4. Simple Square=&lt;br /&gt;
&lt;br /&gt;
=5. Simple Grid=&lt;/div&gt;</summary>
		<author><name>Wakko</name></author>	</entry>

	<entry>
		<id>http://horde3d.org/wiki/index.php?title=Horde3D_Wiki:Community_portal&amp;diff=529</id>
		<title>Horde3D Wiki:Community portal</title>
		<link rel="alternate" type="text/html" href="http://horde3d.org/wiki/index.php?title=Horde3D_Wiki:Community_portal&amp;diff=529"/>
				<updated>2009-08-27T18:33:15Z</updated>
		
		<summary type="html">&lt;p&gt;Wakko: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;__NOEDITSECTION__{{ContentBlock|color=orange&lt;br /&gt;
|content= '''The community portal section of the Horde3D wiki contains community contributed articles that are not part of the official documentation. Feel free to add articles to our wiki or links to external tutorials.'''}}&lt;br /&gt;
{{SpacerBlock}}&lt;br /&gt;
{{ContentBlock|&lt;br /&gt;
|header=Horde3D is a cross-platform graphics engine. The currently supported platform are Windows, Linux and Mac OS X.&lt;br /&gt;
|content={{!!}}&lt;br /&gt;
==Setting up the Development Environment==&lt;br /&gt;
*[[Horde3D Development Environment for Windows]]&lt;br /&gt;
*[[Horde3D Development Environment for Linux]]&lt;br /&gt;
*[[Horde3D Development Environment for Mac OS X]]&lt;br /&gt;
&lt;br /&gt;
*[[Horde3D Development Environment from SVN]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Tutorials==&lt;br /&gt;
[[Category: Tutorials]]&lt;br /&gt;
&lt;br /&gt;
===Beginner===&lt;br /&gt;
#[[Tutorial - Hello World]] - In this section we will create a simple application that loads a character and animates it using a walk cycle.&lt;br /&gt;
#[[Tutorial - Picking]] - In this section we will demonstrate picking the node under the mouse cursor&lt;br /&gt;
#[[Tutorial - Simple HUD]] - How to use showOverlay to create a simple HUD.&lt;br /&gt;
#[[Tutorial - Setup Horde with SDL]]   - How to Setup Horde with SDL.&lt;br /&gt;
#[[Tutorial - Setup Horde with Qt4]]   - How to Setup Horde with Qt4.&lt;br /&gt;
#[[Tutorial - Setup Horde with Gtkmm]] - How to Setup Horde with Gtkmm&lt;br /&gt;
#[[Tutorial - Stereo rendering]] - Basic outline for quad-buffered stereo rendering&lt;br /&gt;
&lt;br /&gt;
===Intermediate===&lt;br /&gt;
#[[Basic Pipeline Tutorial]] - Create your first custom pipeline.&lt;br /&gt;
#[[Procedurally generated geometry tutorial]] - How to create Horde3D compatible procedural geometry (Horde3D 1.0.0 '''Beta 3''' only!).&lt;br /&gt;
&lt;br /&gt;
===Advanced===&lt;br /&gt;
''to come in the future''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Techniques==&lt;br /&gt;
[[Category: Techniques]]&lt;br /&gt;
&lt;br /&gt;
===Shading===&lt;br /&gt;
#[[Shading Technique - Dot Product Detail Texturing]] - Using the dot product of vectors and signed textures for high frequency detail&lt;br /&gt;
#[[Shading Technique - Palette Coloring]] - Quick and dirty palette recoloration of objects&lt;br /&gt;
#[[Shading Technique - Gloss Mapping]] - Mask which areas of an object have specular highlights&lt;br /&gt;
#[[Shading Technique - Glow Mapping]] - Allow areas on an object to emit a strong glowing highlight&lt;br /&gt;
#[[Shading Technique - Fresnel]] - Using reflection and refraction&lt;br /&gt;
#[[Shading Technique - Linear Depth Buffer]] - Create a custom linear depth buffer using vertex&lt;br /&gt;
#[[Shading Technique - Terrain Shading]] - Height and slope based shading with triplanar texturing&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===Preprocessing===&lt;br /&gt;
#[[Preprocessing Technique - Distance Field Vector Textures]] - Using Adobe Photoshop to generate textures suitable for efficient vector art rendering&lt;br /&gt;
&lt;br /&gt;
==Content/Asset Import==&lt;br /&gt;
&lt;br /&gt;
[[Category: Content Import]]&lt;br /&gt;
#[[Collada - 3DS Max and Maya]] - Exporting from 3D Studio Max and Maya.&lt;br /&gt;
#[[Collada - XSI]] - Exporting from XSI.&lt;br /&gt;
#[[Collada - Modo]] - Exporting from Modo.&lt;br /&gt;
#[[Direct Export from Blender]] - Exporting from Blender.&lt;br /&gt;
#[[AC3D]] - Converting AC3D files to Horde3D&lt;br /&gt;
#[[AssetTroubleshooting|Troubleshooting]] - ''&amp;quot;Help, my model is not showing up!&amp;quot;''&lt;br /&gt;
#[[Tips and Techniques]] - Asset creation suggestions &amp;amp; ideas for Horde3d, exporting and program quirks..&lt;br /&gt;
}}&lt;/div&gt;</summary>
		<author><name>Wakko</name></author>	</entry>

	<entry>
		<id>http://horde3d.org/wiki/index.php?title=Horde3D_Wiki:Community_portal&amp;diff=528</id>
		<title>Horde3D Wiki:Community portal</title>
		<link rel="alternate" type="text/html" href="http://horde3d.org/wiki/index.php?title=Horde3D_Wiki:Community_portal&amp;diff=528"/>
				<updated>2009-08-27T18:31:55Z</updated>
		
		<summary type="html">&lt;p&gt;Wakko: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;__NOEDITSECTION__{{ContentBlock|color=orange&lt;br /&gt;
|content= '''The community portal section of the Horde3D wiki contains community contributed articles that are not part of the official documentation. Feel free to add articles to our wiki or links to external tutorials.'''}}&lt;br /&gt;
{{SpacerBlock}}&lt;br /&gt;
{{ContentBlock|&lt;br /&gt;
|header=Horde3D is a cross-platform graphics engine. The currently supported platform are Windows, Linux and Mac OS X.&lt;br /&gt;
|content={{!!}}&lt;br /&gt;
==Setting up the Development Environment==&lt;br /&gt;
*[[Horde3D Development Environment for Windows]]&lt;br /&gt;
*[[Horde3D Development Environment for Linux]]&lt;br /&gt;
*[[Horde3D Development Environment for Mac OS X]]&lt;br /&gt;
&lt;br /&gt;
*[[Horde3D Development Environment from SVN]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Tutorials==&lt;br /&gt;
[[Category: Tutorials]]&lt;br /&gt;
&lt;br /&gt;
===Beginner===&lt;br /&gt;
#[[Tutorial - Hello World]] - In this section we will create a simple application that loads a character and animates it using a walk cycle.&lt;br /&gt;
#[[Tutorial - Picking]] - In this section we will demonstrate picking the node under the mouse cursor&lt;br /&gt;
#[[Tutorial - Simple HUD]] - How to use showOverlay to create a simple HUD.&lt;br /&gt;
#[[Tutorial - Setup Horde with SDL]]   - How to Setup Horde with SDL.&lt;br /&gt;
#[[Tutorial - Setup Horde with Qt4]]   - How to Setup Horde with Qt4.&lt;br /&gt;
#[[Tutorial - Setup Horde with Gtkmm]] - How to Setup Horde with Gtkmm&lt;br /&gt;
#[[Tutorial - Stereo rendering]] - Basic outline for quad-buffered stereo rendering&lt;br /&gt;
&lt;br /&gt;
===Intermediate===&lt;br /&gt;
#[[Basic Pipeline Tutorial]] - Create your first custom pipeline.&lt;br /&gt;
#[[Procedurally generated geometry tutorial]] - How to create Horde3D compatible procedural geometry .&lt;br /&gt;
&lt;br /&gt;
===Advanced===&lt;br /&gt;
''to come in the future''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Techniques==&lt;br /&gt;
[[Category: Techniques]]&lt;br /&gt;
&lt;br /&gt;
===Shading===&lt;br /&gt;
#[[Shading Technique - Dot Product Detail Texturing]] - Using the dot product of vectors and signed textures for high frequency detail&lt;br /&gt;
#[[Shading Technique - Palette Coloring]] - Quick and dirty palette recoloration of objects&lt;br /&gt;
#[[Shading Technique - Gloss Mapping]] - Mask which areas of an object have specular highlights&lt;br /&gt;
#[[Shading Technique - Glow Mapping]] - Allow areas on an object to emit a strong glowing highlight&lt;br /&gt;
#[[Shading Technique - Fresnel]] - Using reflection and refraction&lt;br /&gt;
#[[Shading Technique - Linear Depth Buffer]] - Create a custom linear depth buffer using vertex&lt;br /&gt;
#[[Shading Technique - Terrain Shading]] - Height and slope based shading with triplanar texturing&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===Preprocessing===&lt;br /&gt;
#[[Preprocessing Technique - Distance Field Vector Textures]] - Using Adobe Photoshop to generate textures suitable for efficient vector art rendering&lt;br /&gt;
&lt;br /&gt;
==Content/Asset Import==&lt;br /&gt;
&lt;br /&gt;
[[Category: Content Import]]&lt;br /&gt;
#[[Collada - 3DS Max and Maya]] - Exporting from 3D Studio Max and Maya.&lt;br /&gt;
#[[Collada - XSI]] - Exporting from XSI.&lt;br /&gt;
#[[Collada - Modo]] - Exporting from Modo.&lt;br /&gt;
#[[Direct Export from Blender]] - Exporting from Blender.&lt;br /&gt;
#[[AC3D]] - Converting AC3D files to Horde3D&lt;br /&gt;
#[[AssetTroubleshooting|Troubleshooting]] - ''&amp;quot;Help, my model is not showing up!&amp;quot;''&lt;br /&gt;
#[[Tips and Techniques]] - Asset creation suggestions &amp;amp; ideas for Horde3d, exporting and program quirks..&lt;br /&gt;
}}&lt;/div&gt;</summary>
		<author><name>Wakko</name></author>	</entry>

	<entry>
		<id>http://horde3d.org/wiki/index.php?title=Tutorial_-_Stereo_rendering&amp;diff=525</id>
		<title>Tutorial - Stereo rendering</title>
		<link rel="alternate" type="text/html" href="http://horde3d.org/wiki/index.php?title=Tutorial_-_Stereo_rendering&amp;diff=525"/>
				<updated>2009-07-13T13:03:41Z</updated>
		
		<summary type="html">&lt;p&gt;Wakko: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;'''In this tutorial I will describe how to perform quadbuffered stereo rendering with Horde3D. This explicitly requires a graphics card that supports quad-buffering, i.e. rendering to two different output devices(Nvidia Quadro or ATI/AMD FireGL). This has been tested with a stereo projection system and polarization glasses.'''&lt;br /&gt;
&lt;br /&gt;
To do this we need to render our scene from two different points of view(left and right eye) and send each frame to the corresponding output device.&lt;br /&gt;
&lt;br /&gt;
[http://www.gali-3d.com/archive/articles/StereoOpenGL/StereoscopicOpenGLTutorial.php Stereoscopic OpenGL Tutorial]&lt;br /&gt;
&lt;br /&gt;
[http://www.orthostereo.com/geometryopengl.html Stereoscopic Geometry in OpenGL]&lt;br /&gt;
In this tutorial we will only use an symmetric frustum.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Enable quadbuffering ==&lt;br /&gt;
First of all we need to tell our graphics card to enable quadbuffering if available. The following code shows how to do this using SDL. We will try to enable stereo rendering by default but it will fall back to non-stereo if the graphics card does not have quadbuffering capabilities. We will enable stereo rendering only in fullscreen mode. &lt;br /&gt;
{{CppSourceCode|&lt;br /&gt;
description= SDL Stereo Setup (main.cpp)| &lt;br /&gt;
code=&lt;br /&gt;
&amp;lt;source lang=&amp;quot;cpp&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
bool setupWindow( int width, int height, bool fullscreen )&lt;br /&gt;
{&lt;br /&gt;
	const SDL_VideoInfo* videoInfo = SDL_GetVideoInfo();&lt;br /&gt;
	SDL_Surface* surface;&lt;br /&gt;
&lt;br /&gt;
	appWidth = fullscreen ? videoInfo-&amp;gt;current_w : width;&lt;br /&gt;
	appHeight = fullscreen ? videoInfo-&amp;gt;current_h : height;&lt;br /&gt;
&lt;br /&gt;
	if(fullscreen)&lt;br /&gt;
	{&lt;br /&gt;
		// enable stereo if possible (only in fullscreen mode)&lt;br /&gt;
		if ( SDL_GL_SetAttribute(SDL_GL_STEREO, 1) == 0) {&lt;br /&gt;
			std::cout&amp;lt;&amp;lt;&amp;quot;Stereo flag set!&amp;quot;&amp;lt;&amp;lt;std::endl;&lt;br /&gt;
		}&lt;br /&gt;
		// Try to initialize the SDL_Surface with Stereo enabled&lt;br /&gt;
		if (!(surface =  SDL_SetVideoMode(appWidth,appHeight,32,SDL_OPENGL | SDL_FULLSCREEN | SDL_HWSURFACE))) &lt;br /&gt;
		{&lt;br /&gt;
			// if initialization with stereo enabled failed disable the stereo flag and retry&lt;br /&gt;
			std::cerr &amp;lt;&amp;lt; &amp;quot;STEREO initialization failed! Restarting...&amp;quot;&amp;lt;&amp;lt; std::endl;&lt;br /&gt;
			SDL_GL_SetAttribute(SDL_GL_STEREO, 0);&lt;br /&gt;
			if (!(surface =  SDL_SetVideoMode(appWidth, appHeight, 32, SDL_OPENGL | SDL_FULLSCREEN | SDL_HWSURFACE))) {&lt;br /&gt;
			     std::cerr &amp;lt;&amp;lt; &amp;quot;SDL_SetVideoMode failed: &amp;quot; &amp;lt;&amp;lt; SDL_GetError() &amp;lt;&amp;lt; std::endl;&lt;br /&gt;
			     SDL_Quit();&lt;br /&gt;
			     return 0;&lt;br /&gt;
			}&lt;br /&gt;
		}&lt;br /&gt;
	}else // windowed&lt;br /&gt;
	{	&lt;br /&gt;
		if (!(surface = SDL_SetVideoMode(appWidth,appHeight,32,SDL_OPENGL | SDL_HWSURFACE))) &lt;br /&gt;
		{&lt;br /&gt;
			std::cerr &amp;lt;&amp;lt; &amp;quot;SDL_SetVideoMode failed: &amp;quot; &amp;lt;&amp;lt; SDL_GetError() &amp;lt;&amp;lt; std::endl;&lt;br /&gt;
			SDL_Quit();&lt;br /&gt;
			return 0;&lt;br /&gt;
		}&lt;br /&gt;
		SDL_WM_SetCaption(&amp;quot;SDL App&amp;quot;,NULL);&lt;br /&gt;
	}&lt;br /&gt;
	// check if stereo rendering is enabled&lt;br /&gt;
	int ga = 0;&lt;br /&gt;
	if (SDL_GL_GetAttribute(SDL_GL_STEREO, &amp;amp;ga) == 0) {&lt;br /&gt;
		if (ga == 0)&lt;br /&gt;
			std::cout&amp;lt;&amp;lt;&amp;quot;No stereo rendering available.&amp;quot;&amp;lt;&amp;lt;std::endl;&lt;br /&gt;
		else&lt;br /&gt;
			std::cout&amp;lt;&amp;lt;&amp;quot;Stereo rendering enabled!.&amp;quot;&amp;lt;&amp;lt;std::endl;&lt;br /&gt;
	}&lt;br /&gt;
	return true;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
This will also work with GLFW. Just call this line before opening your GLFW window.&lt;br /&gt;
{{CppSourceCode|&lt;br /&gt;
description= GLFW stereo flag| &lt;br /&gt;
code=&lt;br /&gt;
&amp;lt;source lang=&amp;quot;cpp&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
       glfwOpenWindowHint( GLFW_STEREO, GL_TRUE );&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Render the scene ==&lt;br /&gt;
Now we need to calculate the eye offset and render the scene twice (once for each eye). This is done by switching the Horde3D render buffer to the corresponding eye, moving the camera to the desired eye offset and render the scene to the specified buffer. Again, this will only be done if stereo rendering has been enabled successfully.&lt;br /&gt;
&lt;br /&gt;
We will calculate the eye offset by simply &amp;quot;strafing&amp;quot; the camera from its original position slightly to the left and right and rotating it inwards. This example has some keys assigned to adjust the eye offset and strabismus (&amp;quot;cross-eyedness&amp;quot;) on the fly. In normal (non-stereo) mode we can switch between the eyes to check the camera position even if stereo rendering is not available.&lt;br /&gt;
{{CppSourceCode|&lt;br /&gt;
description= Render the scene (app.cpp)| &lt;br /&gt;
code=&lt;br /&gt;
&amp;lt;source lang=&amp;quot;cpp&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
float eyOffsetFactor = 3.0f;&lt;br /&gt;
float strabismus = 3.0f;&lt;br /&gt;
int eye = 0;&lt;br /&gt;
void Application::mainLoop( int fps )&lt;br /&gt;
{&lt;br /&gt;
	_curFPS = fps;&lt;br /&gt;
	keyHandler();&lt;br /&gt;
	if(! _freeze )&lt;br /&gt;
	{&lt;br /&gt;
		// calculate eye-offsets for stereo rendering&lt;br /&gt;
		float xEyeOffset = eyOffsetFactor*sinf( degToRad( _ry + 90 ) );&lt;br /&gt;
		float zEyeOffset = eyOffsetFactor*cosf( degToRad( _ry + 90 ) );&lt;br /&gt;
&lt;br /&gt;
		// ........ &lt;br /&gt;
&lt;br /&gt;
		// Render scene&lt;br /&gt;
		// render stereo&lt;br /&gt;
		int ga = 0;&lt;br /&gt;
		if (SDL_GL_GetAttribute(SDL_GL_STEREO, &amp;amp;ga) == 0 &amp;amp;&amp;amp; ga == 1) {&lt;br /&gt;
			Horde3D::setNodeParami(_cam, CameraNodeParams::OutputBufferIndex, 0);&lt;br /&gt;
			Horde3D::setNodeTransform( _cam, _x-xEyeOffset, _y, _z-zEyeOffset, _rx ,_ry-strabismus, 0, 1, 1, 1 );&lt;br /&gt;
			Horde3D::render( _cam );&lt;br /&gt;
			Horde3D::setNodeParami(_cam, CameraNodeParams::OutputBufferIndex, 1);&lt;br /&gt;
			Horde3D::setNodeTransform( _cam, _x+xEyeOffset, _y, _z+zEyeOffset, _rx ,_ry+strabismus, 0, 1, 1, 1 );&lt;br /&gt;
			Horde3D::render( _cam );&lt;br /&gt;
		}&lt;br /&gt;
		else { // non stereo&lt;br /&gt;
			// Set camera parameters&lt;br /&gt;
			if (eye == 1)  // left eye&lt;br /&gt;
				Horde3D::setNodeTransform( _cam, _x-xEyeOffset, _y, _z-zEyeOffset, _rx ,_ry-strabismus, 0, 1, 1, 1 );&lt;br /&gt;
			else if (eye == 2)  // right eye&lt;br /&gt;
				Horde3D::setNodeTransform( _cam, _x+xEyeOffset, _y, _z+zEyeOffset, _rx ,_ry+strabismus, 0, 1, 1, 1 );&lt;br /&gt;
			else if(eye == 0)  // normal camera (centered)&lt;br /&gt;
				Horde3D::setNodeTransform( _cam, _x, _y, _z, _rx ,_ry, 0, 1, 1, 1 );&lt;br /&gt;
			Horde3D::render( _cam );&lt;br /&gt;
		}&lt;br /&gt;
		// Remove all overlays&lt;br /&gt;
		Horde3D::clearOverlays();&lt;br /&gt;
	&lt;br /&gt;
		// Write all mesages to log file&lt;br /&gt;
		Horde3DUtils::dumpMessages();&lt;br /&gt;
&lt;br /&gt;
		Horde3D::finalizeFrame(); // comment this line if you are using Horde3D 1.0.0 beta 2&lt;br /&gt;
&lt;br /&gt;
		SDL_GL_SwapBuffers();&lt;br /&gt;
	}&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void Application::keyPressEvent( SDLKey key )&lt;br /&gt;
{&lt;br /&gt;
	// add more key events here...&lt;br /&gt;
&lt;br /&gt;
	// switch between eyes (0: normal/center, 1: left eye, 2: right eye)&lt;br /&gt;
	if( key == SDLK_F5 )	{// F5&lt;br /&gt;
		++eye;&lt;br /&gt;
		if (eye &amp;gt;= 3)&lt;br /&gt;
			eye = 0;&lt;br /&gt;
		std::cout&amp;lt;&amp;lt;&amp;quot;eye: &amp;quot;&amp;lt;&amp;lt;eye&amp;lt;&amp;lt;std::endl;&lt;br /&gt;
	}&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void Application::keyHandler()&lt;br /&gt;
{&lt;br /&gt;
	// add more keys if desired...&lt;br /&gt;
&lt;br /&gt;
	// adjust strabismus (cross eyedness)&lt;br /&gt;
	if(_keys[SDLK_0])&lt;br /&gt;
	{&lt;br /&gt;
		if (strabismus &amp;lt; 45)&lt;br /&gt;
			strabismus += 0.3f;&lt;br /&gt;
	}&lt;br /&gt;
	if(_keys[SDLK_9])&lt;br /&gt;
	{&lt;br /&gt;
		if (strabismus &amp;gt; 0)&lt;br /&gt;
			strabismus -= 0.3f;&lt;br /&gt;
	}&lt;br /&gt;
	// adjust eye offset&lt;br /&gt;
	if(_keys[SDLK_8])&lt;br /&gt;
	{&lt;br /&gt;
		eyeOffset += 0.3f;&lt;br /&gt;
	}&lt;br /&gt;
	if(_keys[SDLK_7])&lt;br /&gt;
	{&lt;br /&gt;
		if (eyeOffset &amp;gt; 0) {&lt;br /&gt;
			eyeOffset -= 0.3f;&lt;br /&gt;
		}&lt;br /&gt;
	}&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
== TODO ==&lt;br /&gt;
- calculate asymmetric frustum&lt;br /&gt;
&lt;br /&gt;
- add a second camera node for easier camera movement&lt;/div&gt;</summary>
		<author><name>Wakko</name></author>	</entry>

	<entry>
		<id>http://horde3d.org/wiki/index.php?title=Tutorial_-_Stereo_rendering&amp;diff=524</id>
		<title>Tutorial - Stereo rendering</title>
		<link rel="alternate" type="text/html" href="http://horde3d.org/wiki/index.php?title=Tutorial_-_Stereo_rendering&amp;diff=524"/>
				<updated>2009-07-12T11:49:27Z</updated>
		
		<summary type="html">&lt;p&gt;Wakko: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;'''In this tutorial I will describe how to perform quadbuffered stereo rendering with Horde3D. This explicitly requires a graphics card that supports quad-buffering, i.e. rendering to two different output devices(Nvidia Quadro or ATI/AMD FireGL). This has been tested with a stereo projection system and polarization glasses.'''&lt;br /&gt;
&lt;br /&gt;
To do this we need to render our scene from two different points of view(left and right eye) and send each frame to the corresponding output device.&lt;br /&gt;
&lt;br /&gt;
[http://www.gali-3d.com/archive/articles/StereoOpenGL/StereoscopicOpenGLTutorial.php Stereoscopic OpenGL Tutorial]&lt;br /&gt;
&lt;br /&gt;
[http://www.orthostereo.com/geometryopengl.html Stereoscopic Geometry in OpenGL]&lt;br /&gt;
In this tutorial we will only use an asymmetric frustum.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Enable quadbuffering ==&lt;br /&gt;
First of all we need to tell our graphics card to enable quadbuffering if available. The following code shows how to do this using SDL. We will try to enable stereo rendering by default but it will fall back to non-stereo if the graphics card does not have quadbuffering capabilities. We will enable stereo rendering only in fullscreen mode. &lt;br /&gt;
{{CppSourceCode|&lt;br /&gt;
description= SDL Stereo Setup (main.cpp)| &lt;br /&gt;
code=&lt;br /&gt;
&amp;lt;source lang=&amp;quot;cpp&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
bool setupWindow( int width, int height, bool fullscreen )&lt;br /&gt;
{&lt;br /&gt;
	const SDL_VideoInfo* videoInfo = SDL_GetVideoInfo();&lt;br /&gt;
	SDL_Surface* surface;&lt;br /&gt;
&lt;br /&gt;
	appWidth = fullscreen ? videoInfo-&amp;gt;current_w : width;&lt;br /&gt;
	appHeight = fullscreen ? videoInfo-&amp;gt;current_h : height;&lt;br /&gt;
&lt;br /&gt;
	if(fullscreen)&lt;br /&gt;
	{&lt;br /&gt;
		// enable stereo if possible (only in fullscreen mode)&lt;br /&gt;
		if ( SDL_GL_SetAttribute(SDL_GL_STEREO, 1) == 0) {&lt;br /&gt;
			std::cout&amp;lt;&amp;lt;&amp;quot;Stereo flag set!&amp;quot;&amp;lt;&amp;lt;std::endl;&lt;br /&gt;
		}&lt;br /&gt;
		// Try to initialize the SDL_Surface with Stereo enabled&lt;br /&gt;
		if (!(surface =  SDL_SetVideoMode(appWidth,appHeight,32,SDL_OPENGL | SDL_FULLSCREEN | SDL_HWSURFACE))) &lt;br /&gt;
		{&lt;br /&gt;
			// if initialization with stereo enabled failed disable the stereo flag and retry&lt;br /&gt;
			std::cerr &amp;lt;&amp;lt; &amp;quot;STEREO initialization failed! Restarting...&amp;quot;&amp;lt;&amp;lt; std::endl;&lt;br /&gt;
			SDL_GL_SetAttribute(SDL_GL_STEREO, 0);&lt;br /&gt;
			if (!(surface =  SDL_SetVideoMode(appWidth, appHeight, 32, SDL_OPENGL | SDL_FULLSCREEN | SDL_HWSURFACE))) {&lt;br /&gt;
			     std::cerr &amp;lt;&amp;lt; &amp;quot;SDL_SetVideoMode failed: &amp;quot; &amp;lt;&amp;lt; SDL_GetError() &amp;lt;&amp;lt; std::endl;&lt;br /&gt;
			     SDL_Quit();&lt;br /&gt;
			     return 0;&lt;br /&gt;
			}&lt;br /&gt;
		}&lt;br /&gt;
	}else // windowed&lt;br /&gt;
	{	&lt;br /&gt;
		if (!(surface = SDL_SetVideoMode(appWidth,appHeight,32,SDL_OPENGL | SDL_HWSURFACE))) &lt;br /&gt;
		{&lt;br /&gt;
			std::cerr &amp;lt;&amp;lt; &amp;quot;SDL_SetVideoMode failed: &amp;quot; &amp;lt;&amp;lt; SDL_GetError() &amp;lt;&amp;lt; std::endl;&lt;br /&gt;
			SDL_Quit();&lt;br /&gt;
			return 0;&lt;br /&gt;
		}&lt;br /&gt;
		SDL_WM_SetCaption(&amp;quot;SDL App&amp;quot;,NULL);&lt;br /&gt;
	}&lt;br /&gt;
	// check if stereo rendering is enabled&lt;br /&gt;
	int ga = 0;&lt;br /&gt;
	if (SDL_GL_GetAttribute(SDL_GL_STEREO, &amp;amp;ga) == 0) {&lt;br /&gt;
		if (ga == 0)&lt;br /&gt;
			std::cout&amp;lt;&amp;lt;&amp;quot;No stereo rendering available.&amp;quot;&amp;lt;&amp;lt;std::endl;&lt;br /&gt;
		else&lt;br /&gt;
			std::cout&amp;lt;&amp;lt;&amp;quot;Stereo rendering enabled!.&amp;quot;&amp;lt;&amp;lt;std::endl;&lt;br /&gt;
	}&lt;br /&gt;
	return true;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
This will also work with GLFW. Just call this line before opening your GLFW window.&lt;br /&gt;
{{CppSourceCode|&lt;br /&gt;
description= GLFW stereo flag| &lt;br /&gt;
code=&lt;br /&gt;
&amp;lt;source lang=&amp;quot;cpp&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
       glfwOpenWindowHint( GLFW_STEREO, GL_TRUE );&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Render the scene ==&lt;br /&gt;
Now we need to calculate the eye offset and render the scene twice (once for each eye). This is done by switching the Horde3D render buffer to the corresponding eye, moving the camera to the desired eye offset and render the scene to the specified buffer. Again, this will only be done if stereo rendering has been enabled successfully.&lt;br /&gt;
&lt;br /&gt;
We will calculate the eye offset by simply &amp;quot;strafing&amp;quot; the camera from its original position slightly to the left and right and rotating it inwards. This example has some keys assigned to adjust the eye offset and strabismus (&amp;quot;cross-eyedness&amp;quot;) on the fly. In normal (non-stereo) mode we can switch between the eyes to check the camera position even if stereo rendering is not available.&lt;br /&gt;
{{CppSourceCode|&lt;br /&gt;
description= Render the scene (app.cpp)| &lt;br /&gt;
code=&lt;br /&gt;
&amp;lt;source lang=&amp;quot;cpp&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
float eyOffsetFactor = 3.0f;&lt;br /&gt;
float strabismus = 3.0f;&lt;br /&gt;
int eye = 0;&lt;br /&gt;
void Application::mainLoop( int fps )&lt;br /&gt;
{&lt;br /&gt;
	_curFPS = fps;&lt;br /&gt;
	keyHandler();&lt;br /&gt;
	if(! _freeze )&lt;br /&gt;
	{&lt;br /&gt;
		// calculate eye-offsets for stereo rendering&lt;br /&gt;
		float xEyeOffset = eyOffsetFactor*sinf( degToRad( _ry + 90 ) );&lt;br /&gt;
		float zEyeOffset = eyOffsetFactor*cosf( degToRad( _ry + 90 ) );&lt;br /&gt;
&lt;br /&gt;
		// ........ &lt;br /&gt;
&lt;br /&gt;
		// Render scene&lt;br /&gt;
		// render stereo&lt;br /&gt;
		int ga = 0;&lt;br /&gt;
		if (SDL_GL_GetAttribute(SDL_GL_STEREO, &amp;amp;ga) == 0 &amp;amp;&amp;amp; ga == 1) {&lt;br /&gt;
			Horde3D::setNodeParami(_cam, CameraNodeParams::OutputBufferIndex, 0);&lt;br /&gt;
			Horde3D::setNodeTransform( _cam, _x-xEyeOffset, _y, _z-zEyeOffset, _rx ,_ry-strabismus, 0, 1, 1, 1 );&lt;br /&gt;
			Horde3D::render( _cam );&lt;br /&gt;
			Horde3D::setNodeParami(_cam, CameraNodeParams::OutputBufferIndex, 1);&lt;br /&gt;
			Horde3D::setNodeTransform( _cam, _x+xEyeOffset, _y, _z+zEyeOffset, _rx ,_ry+strabismus, 0, 1, 1, 1 );&lt;br /&gt;
			Horde3D::render( _cam );&lt;br /&gt;
		}&lt;br /&gt;
		else { // non stereo&lt;br /&gt;
			// Set camera parameters&lt;br /&gt;
			if (eye == 1)  // left eye&lt;br /&gt;
				Horde3D::setNodeTransform( _cam, _x-xEyeOffset, _y, _z-zEyeOffset, _rx ,_ry-strabismus, 0, 1, 1, 1 );&lt;br /&gt;
			else if (eye == 2)  // right eye&lt;br /&gt;
				Horde3D::setNodeTransform( _cam, _x+xEyeOffset, _y, _z+zEyeOffset, _rx ,_ry+strabismus, 0, 1, 1, 1 );&lt;br /&gt;
			else if(eye == 0)  // normal camera (centered)&lt;br /&gt;
				Horde3D::setNodeTransform( _cam, _x, _y, _z, _rx ,_ry, 0, 1, 1, 1 );&lt;br /&gt;
			Horde3D::render( _cam );&lt;br /&gt;
		}&lt;br /&gt;
		// Remove all overlays&lt;br /&gt;
		Horde3D::clearOverlays();&lt;br /&gt;
	&lt;br /&gt;
		// Write all mesages to log file&lt;br /&gt;
		Horde3DUtils::dumpMessages();&lt;br /&gt;
&lt;br /&gt;
		Horde3D::finalizeFrame(); // comment this line if you are using Horde3D 1.0.0 beta 2&lt;br /&gt;
&lt;br /&gt;
		SDL_GL_SwapBuffers();&lt;br /&gt;
	}&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void Application::keyPressEvent( SDLKey key )&lt;br /&gt;
{&lt;br /&gt;
	// add more key events here...&lt;br /&gt;
&lt;br /&gt;
	// switch between eyes (0: normal/center, 1: left eye, 2: right eye)&lt;br /&gt;
	if( key == SDLK_F5 )	{// F5&lt;br /&gt;
		++eye;&lt;br /&gt;
		if (eye &amp;gt;= 3)&lt;br /&gt;
			eye = 0;&lt;br /&gt;
		std::cout&amp;lt;&amp;lt;&amp;quot;eye: &amp;quot;&amp;lt;&amp;lt;eye&amp;lt;&amp;lt;std::endl;&lt;br /&gt;
	}&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void Application::keyHandler()&lt;br /&gt;
{&lt;br /&gt;
	// add more keys if desired...&lt;br /&gt;
&lt;br /&gt;
	// adjust strabismus (cross eyedness)&lt;br /&gt;
	if(_keys[SDLK_0])&lt;br /&gt;
	{&lt;br /&gt;
		if (strabismus &amp;lt; 45)&lt;br /&gt;
			strabismus += 0.3f;&lt;br /&gt;
	}&lt;br /&gt;
	if(_keys[SDLK_9])&lt;br /&gt;
	{&lt;br /&gt;
		if (strabismus &amp;gt; 0)&lt;br /&gt;
			strabismus -= 0.3f;&lt;br /&gt;
	}&lt;br /&gt;
	// adjust eye offset&lt;br /&gt;
	if(_keys[SDLK_8])&lt;br /&gt;
	{&lt;br /&gt;
		eyeOffset += 0.3f;&lt;br /&gt;
	}&lt;br /&gt;
	if(_keys[SDLK_7])&lt;br /&gt;
	{&lt;br /&gt;
		if (eyeOffset &amp;gt; 0) {&lt;br /&gt;
			eyeOffset -= 0.3f;&lt;br /&gt;
		}&lt;br /&gt;
	}&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
== TODO ==&lt;br /&gt;
- calculate symmetric frustum&lt;br /&gt;
&lt;br /&gt;
- add a second camera node for easier camera movement&lt;/div&gt;</summary>
		<author><name>Wakko</name></author>	</entry>

	<entry>
		<id>http://horde3d.org/wiki/index.php?title=Tutorial_-_Stereo_rendering&amp;diff=523</id>
		<title>Tutorial - Stereo rendering</title>
		<link rel="alternate" type="text/html" href="http://horde3d.org/wiki/index.php?title=Tutorial_-_Stereo_rendering&amp;diff=523"/>
				<updated>2009-07-12T11:41:40Z</updated>
		
		<summary type="html">&lt;p&gt;Wakko: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;'''In this tutorial I will describe how to perform quadbuffered stereo rendering with Horde3D. This explicitly requires a graphics card that supports quad-buffering, i.e. rendering to two different output devices(Nvidia Quadro or ATI/AMD FireGL). This has been tested with a stereo projection system and polarization glasses.'''&lt;br /&gt;
&lt;br /&gt;
To do this we need to render our scene from two different points of view(left and right eye) and send each frame to the corresponding output device.&lt;br /&gt;
&lt;br /&gt;
[http://www.gali-3d.com/archive/articles/StereoOpenGL/StereoscopicOpenGLTutorial.php Stereoscopic OpenGL Tutorial]&lt;br /&gt;
&lt;br /&gt;
[http://www.orthostereo.com/geometryopengl.html Stereoscopic Geometry in OpenGL]&lt;br /&gt;
In this tutorial we will only use an asymmetric frustum.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Enable quadbuffering ==&lt;br /&gt;
First of all we need to tell our graphics card to enable quadbuffering if available. The following code shows how to do this using SDL. We will try to enable stereo rendering by default but it will fall back to non-stereo if the graphics card does not have quadbuffering capabilities. We will enable stereo rendering only in fullscreen mode. &lt;br /&gt;
{{CppSourceCode|&lt;br /&gt;
description= SDL Stereo Setup (main.cpp)| &lt;br /&gt;
code=&lt;br /&gt;
&amp;lt;source lang=&amp;quot;cpp&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
bool setupWindow( int width, int height, bool fullscreen )&lt;br /&gt;
{&lt;br /&gt;
	const SDL_VideoInfo* videoInfo = SDL_GetVideoInfo();&lt;br /&gt;
	SDL_Surface* surface;&lt;br /&gt;
&lt;br /&gt;
	appWidth = fullscreen ? videoInfo-&amp;gt;current_w : width;&lt;br /&gt;
	appHeight = fullscreen ? videoInfo-&amp;gt;current_h : height;&lt;br /&gt;
&lt;br /&gt;
	if(fullscreen)&lt;br /&gt;
	{&lt;br /&gt;
		// enable stereo if possible (only in fullscreen mode)&lt;br /&gt;
		if ( SDL_GL_SetAttribute(SDL_GL_STEREO, 1) == 0) {&lt;br /&gt;
			std::cout&amp;lt;&amp;lt;&amp;quot;Stereo flag set!&amp;quot;&amp;lt;&amp;lt;std::endl;&lt;br /&gt;
		}&lt;br /&gt;
		// Try to initialize the SDL_Surface with Stereo enabled&lt;br /&gt;
		if (!(surface =  SDL_SetVideoMode(appWidth,appHeight,32,SDL_OPENGL | SDL_FULLSCREEN | SDL_HWSURFACE))) &lt;br /&gt;
		{&lt;br /&gt;
			// if initialization with stereo enabled failed disable the stereo flag and retry&lt;br /&gt;
			std::cerr &amp;lt;&amp;lt; &amp;quot;STEREO initialization failed! Restarting...&amp;quot;&amp;lt;&amp;lt; std::endl;&lt;br /&gt;
			SDL_GL_SetAttribute(SDL_GL_STEREO, 0);&lt;br /&gt;
			if (!(surface =  SDL_SetVideoMode(appWidth, appHeight, 32, SDL_OPENGL | SDL_FULLSCREEN | SDL_HWSURFACE))) {&lt;br /&gt;
			     std::cerr &amp;lt;&amp;lt; &amp;quot;SDL_SetVideoMode failed: &amp;quot; &amp;lt;&amp;lt; SDL_GetError() &amp;lt;&amp;lt; std::endl;&lt;br /&gt;
			     SDL_Quit();&lt;br /&gt;
			     return 0;&lt;br /&gt;
			}&lt;br /&gt;
		}&lt;br /&gt;
	}else // windowed&lt;br /&gt;
	{	&lt;br /&gt;
		if (!(surface = SDL_SetVideoMode(appWidth,appHeight,32,SDL_OPENGL | SDL_HWSURFACE))) &lt;br /&gt;
		{&lt;br /&gt;
			std::cerr &amp;lt;&amp;lt; &amp;quot;SDL_SetVideoMode failed: &amp;quot; &amp;lt;&amp;lt; SDL_GetError() &amp;lt;&amp;lt; std::endl;&lt;br /&gt;
			SDL_Quit();&lt;br /&gt;
			return 0;&lt;br /&gt;
		}&lt;br /&gt;
		SDL_WM_SetCaption(&amp;quot;SDL App&amp;quot;,NULL);&lt;br /&gt;
	}&lt;br /&gt;
	// check if stereo rendering is enabled&lt;br /&gt;
	int ga = 0;&lt;br /&gt;
	if (SDL_GL_GetAttribute(SDL_GL_STEREO, &amp;amp;ga) == 0) {&lt;br /&gt;
		if (ga == 0)&lt;br /&gt;
			std::cout&amp;lt;&amp;lt;&amp;quot;No stereo rendering available.&amp;quot;&amp;lt;&amp;lt;std::endl;&lt;br /&gt;
		else&lt;br /&gt;
			std::cout&amp;lt;&amp;lt;&amp;quot;Stereo rendering enabled!.&amp;quot;&amp;lt;&amp;lt;std::endl;&lt;br /&gt;
	}&lt;br /&gt;
	return true;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
This will also work with GLFW. Just call this line before opening your GLFW window.&lt;br /&gt;
{{CppSourceCode|&lt;br /&gt;
description= GLFW stereo flag| &lt;br /&gt;
code=&lt;br /&gt;
&amp;lt;source lang=&amp;quot;cpp&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
       glfwOpenWindowHint( GLFW_STEREO, GL_TRUE );&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Render the scene ==&lt;br /&gt;
Now we need to calculate the eye offset and render the scene twice for both eyes. This is done by switching the Horde3D render buffer for each eye, moving the camera to the desired eye offset and render the scene to the specified buffer. Again, this will only be done if stereo rendering was enabled successfully.&lt;br /&gt;
&lt;br /&gt;
We will calculate the eye offset by simply &amp;quot;strafing&amp;quot; the camera from its original position slightly to the left and right and rotating it inwards. This example has some keys assigned to adjust the eye offset and strabismus (&amp;quot;cross-eyedness&amp;quot;) on the fly. In normal (non-stereo) mode we can switch between the eyes to check the camera position even if stereo rendering is not available.&lt;br /&gt;
{{CppSourceCode|&lt;br /&gt;
description= Render the scene (app.cpp)| &lt;br /&gt;
code=&lt;br /&gt;
&amp;lt;source lang=&amp;quot;cpp&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
float eyOffsetFactor = 3.0f;&lt;br /&gt;
float strabismus = 3.0f;&lt;br /&gt;
int eye = 0;&lt;br /&gt;
void Application::mainLoop( int fps )&lt;br /&gt;
{&lt;br /&gt;
	_curFPS = fps;&lt;br /&gt;
	keyHandler();&lt;br /&gt;
	if(! _freeze )&lt;br /&gt;
	{&lt;br /&gt;
		// calculate eye-offsets for stereo rendering&lt;br /&gt;
		float xEyeOffset = eyOffsetFactor*sinf( degToRad( _ry + 90 ) );&lt;br /&gt;
		float zEyeOffset = eyOffsetFactor*cosf( degToRad( _ry + 90 ) );&lt;br /&gt;
&lt;br /&gt;
		// ........ &lt;br /&gt;
&lt;br /&gt;
		// Render scene&lt;br /&gt;
		// render stereo&lt;br /&gt;
		int ga = 0;&lt;br /&gt;
		if (SDL_GL_GetAttribute(SDL_GL_STEREO, &amp;amp;ga) == 0 &amp;amp;&amp;amp; ga == 1) {&lt;br /&gt;
			Horde3D::setNodeParami(_cam, CameraNodeParams::OutputBufferIndex, 0);&lt;br /&gt;
			Horde3D::setNodeTransform( _cam, _x-xEyeOffset, _y, _z-zEyeOffset, _rx ,_ry-strabismus, 0, 1, 1, 1 );&lt;br /&gt;
			Horde3D::render( _cam );&lt;br /&gt;
			Horde3D::setNodeParami(_cam, CameraNodeParams::OutputBufferIndex, 1);&lt;br /&gt;
			Horde3D::setNodeTransform( _cam, _x+xEyeOffset, _y, _z+zEyeOffset, _rx ,_ry+strabismus, 0, 1, 1, 1 );&lt;br /&gt;
			Horde3D::render( _cam );&lt;br /&gt;
		}&lt;br /&gt;
		else { // non stereo&lt;br /&gt;
			// Set camera parameters&lt;br /&gt;
			if (eye == 1)  // left eye&lt;br /&gt;
				Horde3D::setNodeTransform( _cam, _x-xEyeOffset, _y, _z-zEyeOffset, _rx ,_ry-strabismus, 0, 1, 1, 1 );&lt;br /&gt;
			else if (eye == 2)  // right eye&lt;br /&gt;
				Horde3D::setNodeTransform( _cam, _x+xEyeOffset, _y, _z+zEyeOffset, _rx ,_ry+strabismus, 0, 1, 1, 1 );&lt;br /&gt;
			else if(eye == 0)  // normal camera (centered)&lt;br /&gt;
				Horde3D::setNodeTransform( _cam, _x, _y, _z, _rx ,_ry, 0, 1, 1, 1 );&lt;br /&gt;
			Horde3D::render( _cam );&lt;br /&gt;
		}&lt;br /&gt;
		// Remove all overlays&lt;br /&gt;
		Horde3D::clearOverlays();&lt;br /&gt;
	&lt;br /&gt;
		// Write all mesages to log file&lt;br /&gt;
		Horde3DUtils::dumpMessages();&lt;br /&gt;
&lt;br /&gt;
		Horde3D::finalizeFrame(); // comment this line if you are using Horde3D 1.0.0 beta 2&lt;br /&gt;
&lt;br /&gt;
		SDL_GL_SwapBuffers();&lt;br /&gt;
	}&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void Application::keyPressEvent( SDLKey key )&lt;br /&gt;
{&lt;br /&gt;
	// add more key events here...&lt;br /&gt;
&lt;br /&gt;
	// switch between eyes (0: normal/center, 1: left eye, 2: right eye)&lt;br /&gt;
	if( key == SDLK_F5 )	{// F5&lt;br /&gt;
		++eye;&lt;br /&gt;
		if (eye &amp;gt;= 3)&lt;br /&gt;
			eye = 0;&lt;br /&gt;
		std::cout&amp;lt;&amp;lt;&amp;quot;eye: &amp;quot;&amp;lt;&amp;lt;eye&amp;lt;&amp;lt;std::endl;&lt;br /&gt;
	}&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void Application::keyHandler()&lt;br /&gt;
{&lt;br /&gt;
	// add more keys if desired...&lt;br /&gt;
&lt;br /&gt;
	// adjust strabismus (cross eyedness)&lt;br /&gt;
	if(_keys[SDLK_0])&lt;br /&gt;
	{&lt;br /&gt;
		if (strabismus &amp;lt; 45)&lt;br /&gt;
			strabismus += 0.3f;&lt;br /&gt;
	}&lt;br /&gt;
	if(_keys[SDLK_9])&lt;br /&gt;
	{&lt;br /&gt;
		if (strabismus &amp;gt; 0)&lt;br /&gt;
			strabismus -= 0.3f;&lt;br /&gt;
	}&lt;br /&gt;
	// adjust eye offset&lt;br /&gt;
	if(_keys[SDLK_8])&lt;br /&gt;
	{&lt;br /&gt;
		eyeOffset += 0.3f;&lt;br /&gt;
	}&lt;br /&gt;
	if(_keys[SDLK_7])&lt;br /&gt;
	{&lt;br /&gt;
		if (eyeOffset &amp;gt; 0) {&lt;br /&gt;
			eyeOffset -= 0.3f;&lt;br /&gt;
		}&lt;br /&gt;
	}&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
== TODO ==&lt;br /&gt;
- calculate symmetric frustum&lt;br /&gt;
&lt;br /&gt;
- add a second camera node for easier camera movement&lt;/div&gt;</summary>
		<author><name>Wakko</name></author>	</entry>

	<entry>
		<id>http://horde3d.org/wiki/index.php?title=Tutorial_-_Stereo_rendering&amp;diff=522</id>
		<title>Tutorial - Stereo rendering</title>
		<link rel="alternate" type="text/html" href="http://horde3d.org/wiki/index.php?title=Tutorial_-_Stereo_rendering&amp;diff=522"/>
				<updated>2009-07-12T11:41:22Z</updated>
		
		<summary type="html">&lt;p&gt;Wakko: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;'''In this tutorial I will describe how to perform quadbuffered stereo rendering with Horde3D. This explicitly requires a graphics card that supports quad-buffering, i.e. rendering to two different output devices(Nvidia Quadro or ATI/AMD FireGL). This has been tested with a stereo projection system and polarization glasses.'''&lt;br /&gt;
&lt;br /&gt;
To do this we need to render our scene from two different points of view(left and right eye) and send each frame to the corresponding output device.&lt;br /&gt;
&lt;br /&gt;
[http://www.gali-3d.com/archive/articles/StereoOpenGL/StereoscopicOpenGLTutorial.php Stereoscopic OpenGL Tutorial]&lt;br /&gt;
&lt;br /&gt;
[http://www.orthostereo.com/geometryopengl.html Stereoscopic Geometry in OpenGL]&lt;br /&gt;
In this tutorial we will only use an asymmetric frustum.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Enable quadbuffering ==&lt;br /&gt;
First of all we need to tell our graphics card to enable quadbuffering if available. The following code shows how to do this using SDL. We will try to enable stereo rendering by default but it will fall back to non-stereo if the graphics card does not have quadbuffering capabilities. We will enable stereo rendering only in fullscreen mode. &lt;br /&gt;
{{CppSourceCode|&lt;br /&gt;
description= SDL Stereo Setup (main.cpp)| &lt;br /&gt;
code=&lt;br /&gt;
&amp;lt;source lang=&amp;quot;cpp&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
bool setupWindow( int width, int height, bool fullscreen )&lt;br /&gt;
{&lt;br /&gt;
	const SDL_VideoInfo* videoInfo = SDL_GetVideoInfo();&lt;br /&gt;
	SDL_Surface* surface;&lt;br /&gt;
&lt;br /&gt;
	appWidth = fullscreen ? videoInfo-&amp;gt;current_w : width;&lt;br /&gt;
	appHeight = fullscreen ? videoInfo-&amp;gt;current_h : height;&lt;br /&gt;
&lt;br /&gt;
	if(fullscreen)&lt;br /&gt;
	{&lt;br /&gt;
		// enable stereo if possible (only in fullscreen mode)&lt;br /&gt;
		if ( SDL_GL_SetAttribute(SDL_GL_STEREO, 1) == 0) {&lt;br /&gt;
			std::cout&amp;lt;&amp;lt;&amp;quot;Stereo flag set!&amp;quot;&amp;lt;&amp;lt;std::endl;&lt;br /&gt;
		}&lt;br /&gt;
		// Try to initialize the SDL_Surface with Stereo enabled&lt;br /&gt;
		if (!(surface =  SDL_SetVideoMode(appWidth,appHeight,32,SDL_OPENGL | SDL_FULLSCREEN | SDL_HWSURFACE))) &lt;br /&gt;
		{&lt;br /&gt;
			// if initialization with stereo enabled failed disable the stereo flag and retry&lt;br /&gt;
			std::cerr &amp;lt;&amp;lt; &amp;quot;STEREO initialization failed! Restarting...&amp;quot;&amp;lt;&amp;lt; std::endl;&lt;br /&gt;
			SDL_GL_SetAttribute(SDL_GL_STEREO, 0);&lt;br /&gt;
			if (!(surface =  SDL_SetVideoMode(appWidth, appHeight, 32, SDL_OPENGL | SDL_FULLSCREEN | SDL_HWSURFACE))) {&lt;br /&gt;
			     std::cerr &amp;lt;&amp;lt; &amp;quot;SDL_SetVideoMode failed: &amp;quot; &amp;lt;&amp;lt; SDL_GetError() &amp;lt;&amp;lt; std::endl;&lt;br /&gt;
			     SDL_Quit();&lt;br /&gt;
			     return 0;&lt;br /&gt;
			}&lt;br /&gt;
		}&lt;br /&gt;
	}else // windowed&lt;br /&gt;
	{	&lt;br /&gt;
		if (!(surface = SDL_SetVideoMode(appWidth,appHeight,32,SDL_OPENGL | SDL_HWSURFACE))) &lt;br /&gt;
		{&lt;br /&gt;
			std::cerr &amp;lt;&amp;lt; &amp;quot;SDL_SetVideoMode failed: &amp;quot; &amp;lt;&amp;lt; SDL_GetError() &amp;lt;&amp;lt; std::endl;&lt;br /&gt;
			SDL_Quit();&lt;br /&gt;
			return 0;&lt;br /&gt;
		}&lt;br /&gt;
		SDL_WM_SetCaption(&amp;quot;SDL App&amp;quot;,NULL);&lt;br /&gt;
	}&lt;br /&gt;
	// check if stereo rendering is enabled&lt;br /&gt;
	int ga = 0;&lt;br /&gt;
	if (SDL_GL_GetAttribute(SDL_GL_STEREO, &amp;amp;ga) == 0) {&lt;br /&gt;
		if (ga == 0)&lt;br /&gt;
			std::cout&amp;lt;&amp;lt;&amp;quot;No stereo rendering available.&amp;quot;&amp;lt;&amp;lt;std::endl;&lt;br /&gt;
		else&lt;br /&gt;
			std::cout&amp;lt;&amp;lt;&amp;quot;Stereo rendering enabled!.&amp;quot;&amp;lt;&amp;lt;std::endl;&lt;br /&gt;
	}&lt;br /&gt;
	return true;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
This will also work with GLFW. Just call this line before opening your GLFW window.&lt;br /&gt;
{{CppSourceCode|&lt;br /&gt;
description= GLFW stereo flag| &lt;br /&gt;
code=&lt;br /&gt;
&amp;lt;source lang=&amp;quot;cpp&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
       glfwOpenWindowHint( GLFW_STEREO, GL_TRUE );&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Render the scene ==&lt;br /&gt;
Now we need to calculate the eye offset and render the scene twice for both eyes. This is done by switching the Horde3D render buffer for each eye, moving the camera to the desired eye offset and render the scene to the specified buffer. Again, this will only be done if stereo rendering was enabled successfully.&lt;br /&gt;
&lt;br /&gt;
We will calculate the eye offset by simply &amp;quot;strafing&amp;quot; the camera from its original position slightly to the left and right and rotating it inwards. This example has some keys assigned to adjust the eye offset and strabismus (&amp;quot;cross-eyedness&amp;quot;) on the fly. In normal (non-stereo) mode we can switch between the eyes to check the camera position even if stereo rendering is not available.&lt;br /&gt;
{{CppSourceCode|&lt;br /&gt;
description= Render the scene (app.cpp)| &lt;br /&gt;
code=&lt;br /&gt;
&amp;lt;source lang=&amp;quot;cpp&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
float eyOffsetFactor = 3.0f;&lt;br /&gt;
float strabismus = 3.0f;&lt;br /&gt;
int eye = 0;&lt;br /&gt;
void Application::mainLoop( int fps )&lt;br /&gt;
{&lt;br /&gt;
	_curFPS = fps;&lt;br /&gt;
	keyHandler();&lt;br /&gt;
	if(! _freeze )&lt;br /&gt;
	{&lt;br /&gt;
		// calculate eye-offsets for stereo rendering&lt;br /&gt;
		float xEyeOffset = eyOffsetFactor*sinf( degToRad( _ry + 90 ) );&lt;br /&gt;
		float zEyeOffset = eyOffsetFactor*cosf( degToRad( _ry + 90 ) );&lt;br /&gt;
&lt;br /&gt;
		// ........ &lt;br /&gt;
&lt;br /&gt;
		// Render scene&lt;br /&gt;
		// render stereo&lt;br /&gt;
		int ga = 0;&lt;br /&gt;
		if (SDL_GL_GetAttribute(SDL_GL_STEREO, &amp;amp;ga) == 0 &amp;amp;&amp;amp; ga == 1) {&lt;br /&gt;
			Horde3D::setNodeParami(_cam, CameraNodeParams::OutputBufferIndex, 0);&lt;br /&gt;
			Horde3D::setNodeTransform( _cam, _x-xEyeOffset, _y, _z-zEyeOffset, _rx ,_ry-strabismus, 0, 1, 1, 1 );&lt;br /&gt;
			Horde3D::render( _cam );&lt;br /&gt;
			Horde3D::setNodeParami(_cam, CameraNodeParams::OutputBufferIndex, 1);&lt;br /&gt;
			Horde3D::setNodeTransform( _cam, _x+xEyeOffset, _y, _z+zEyeOffset, _rx ,_ry+strabismus, 0, 1, 1, 1 );&lt;br /&gt;
			Horde3D::render( _cam );&lt;br /&gt;
		}&lt;br /&gt;
		else { // non stereo&lt;br /&gt;
			// Set camera parameters&lt;br /&gt;
			if (eye == 1)  // left eye&lt;br /&gt;
				Horde3D::setNodeTransform( _cam, _x-xEyeOffset, _y, _z-zEyeOffset, _rx ,_ry-strabismus, 0, 1, 1, 1 );&lt;br /&gt;
			else if (eye == 2)  // right eye&lt;br /&gt;
				Horde3D::setNodeTransform( _cam, _x+xEyeOffset, _y, _z+zEyeOffset, _rx ,_ry+strabismus, 0, 1, 1, 1 );&lt;br /&gt;
			else if(eye == 0)  // normal camera (centered)&lt;br /&gt;
				Horde3D::setNodeTransform( _cam, _x, _y, _z, _rx ,_ry, 0, 1, 1, 1 );&lt;br /&gt;
			Horde3D::render( _cam );&lt;br /&gt;
		}&lt;br /&gt;
		// Remove all overlays&lt;br /&gt;
		Horde3D::clearOverlays();&lt;br /&gt;
	&lt;br /&gt;
		// Write all mesages to log file&lt;br /&gt;
		Horde3DUtils::dumpMessages();&lt;br /&gt;
&lt;br /&gt;
		Horde3D::finalizeFrame(); // comment this line if you are using Horde3D 1.0.0 beta 2&lt;br /&gt;
&lt;br /&gt;
		SDL_GL_SwapBuffers();&lt;br /&gt;
	}&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void Application::keyPressEvent( SDLKey key )&lt;br /&gt;
{&lt;br /&gt;
	// add more key events here...&lt;br /&gt;
&lt;br /&gt;
	// switch between eyes (0: normal/center, 1: left eye, 2: right eye)&lt;br /&gt;
	if( key == SDLK_F5 )	{// F5&lt;br /&gt;
		++eye;&lt;br /&gt;
		if (eye &amp;gt;= 3)&lt;br /&gt;
			eye = 0;&lt;br /&gt;
		std::cout&amp;lt;&amp;lt;&amp;quot;eye: &amp;quot;&amp;lt;&amp;lt;eye&amp;lt;&amp;lt;std::endl;&lt;br /&gt;
	}&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void Application::keyHandler()&lt;br /&gt;
{&lt;br /&gt;
	// add more keys if desired...&lt;br /&gt;
&lt;br /&gt;
	// adjust strabismus (cross eyedness)&lt;br /&gt;
	if(_keys[SDLK_0])&lt;br /&gt;
	{&lt;br /&gt;
		if (strabismus &amp;lt; 45)&lt;br /&gt;
			strabismus += 0.3f;&lt;br /&gt;
	}&lt;br /&gt;
	if(_keys[SDLK_9])&lt;br /&gt;
	{&lt;br /&gt;
		if (strabismus &amp;gt; 0)&lt;br /&gt;
			strabismus -= 0.3f;&lt;br /&gt;
	}&lt;br /&gt;
	// adjust eye offset&lt;br /&gt;
	if(_keys[SDLK_8])&lt;br /&gt;
	{&lt;br /&gt;
		eyeOffset += 0.3f;&lt;br /&gt;
	}&lt;br /&gt;
	if(_keys[SDLK_7])&lt;br /&gt;
	{&lt;br /&gt;
		if (eyeOffset &amp;gt; 0) {&lt;br /&gt;
			eyeOffset -= 0.3f;&lt;br /&gt;
		}&lt;br /&gt;
	}&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
== TODO ==&lt;br /&gt;
- calculate symmetric frustum&lt;br /&gt;
- add a second camera node for easier camera movement&lt;/div&gt;</summary>
		<author><name>Wakko</name></author>	</entry>

	<entry>
		<id>http://horde3d.org/wiki/index.php?title=Tutorial_-_Stereo_rendering&amp;diff=518</id>
		<title>Tutorial - Stereo rendering</title>
		<link rel="alternate" type="text/html" href="http://horde3d.org/wiki/index.php?title=Tutorial_-_Stereo_rendering&amp;diff=518"/>
				<updated>2009-07-11T12:24:48Z</updated>
		
		<summary type="html">&lt;p&gt;Wakko: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;'''In this tutorial I will describe how to perform quadbuffered stereo rendering with Horde3D. This explicitly requires a graphics card that supports quad-buffering, i.e. rendering to two different output devices(Nvidia Quadro or ATI/AMD FireGL). This has been tested with a stereo projection system and polarization glasses.'''&lt;br /&gt;
&lt;br /&gt;
To do this we need to render our scene from two different points of view(left and right eye) and send each frame to the corresponding output device.&lt;br /&gt;
&lt;br /&gt;
[http://www.gali-3d.com/archive/articles/StereoOpenGL/StereoscopicOpenGLTutorial.php Stereoscopic OpenGL Tutorial]&lt;br /&gt;
&lt;br /&gt;
[http://www.orthostereo.com/geometryopengl.html Stereoscopic Geometry in OpenGL]&lt;br /&gt;
In this tutorial we will only use an asymmetric frustum.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Enable quadbuffering ==&lt;br /&gt;
First of all we need to tell our graphics card to enable quadbuffering if available. The following code shows how to do this using SDL. We will try to enable stereo rendering by default but it will fall back to non-stereo if the graphics card does not have quadbuffering capabilities. We will enable stereo rendering only in fullscreen mode. &lt;br /&gt;
{{CppSourceCode|&lt;br /&gt;
description= SDL Stereo Setup (main.cpp)| &lt;br /&gt;
code=&lt;br /&gt;
&amp;lt;source lang=&amp;quot;cpp&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
bool setupWindow( int width, int height, bool fullscreen )&lt;br /&gt;
{&lt;br /&gt;
	const SDL_VideoInfo* videoInfo = SDL_GetVideoInfo();&lt;br /&gt;
	SDL_Surface* surface;&lt;br /&gt;
&lt;br /&gt;
	appWidth = fullscreen ? videoInfo-&amp;gt;current_w : width;&lt;br /&gt;
	appHeight = fullscreen ? videoInfo-&amp;gt;current_h : height;&lt;br /&gt;
&lt;br /&gt;
	if(fullscreen)&lt;br /&gt;
	{&lt;br /&gt;
		// enable stereo if possible (only in fullscreen mode)&lt;br /&gt;
		if ( SDL_GL_SetAttribute(SDL_GL_STEREO, 1) == 0) {&lt;br /&gt;
			std::cout&amp;lt;&amp;lt;&amp;quot;Stereo flag set!&amp;quot;&amp;lt;&amp;lt;std::endl;&lt;br /&gt;
		}&lt;br /&gt;
		// Try to initialize the SDL_Surface with Stereo enabled&lt;br /&gt;
		if (!(surface =  SDL_SetVideoMode(appWidth,appHeight,32,SDL_OPENGL | SDL_FULLSCREEN | SDL_HWSURFACE))) &lt;br /&gt;
		{&lt;br /&gt;
			// if initialization with stereo enabled failed disable the stereo flag and retry&lt;br /&gt;
			std::cerr &amp;lt;&amp;lt; &amp;quot;STEREO initialization failed! Restarting...&amp;quot;&amp;lt;&amp;lt; std::endl;&lt;br /&gt;
			SDL_GL_SetAttribute(SDL_GL_STEREO, 0);&lt;br /&gt;
			if (!(surface =  SDL_SetVideoMode(appWidth, appHeight, 32, SDL_OPENGL | SDL_FULLSCREEN | SDL_HWSURFACE))) {&lt;br /&gt;
			     std::cerr &amp;lt;&amp;lt; &amp;quot;SDL_SetVideoMode failed: &amp;quot; &amp;lt;&amp;lt; SDL_GetError() &amp;lt;&amp;lt; std::endl;&lt;br /&gt;
			     SDL_Quit();&lt;br /&gt;
			     return 0;&lt;br /&gt;
			}&lt;br /&gt;
		}&lt;br /&gt;
	}else // windowed&lt;br /&gt;
	{	&lt;br /&gt;
		if (!(surface = SDL_SetVideoMode(appWidth,appHeight,32,SDL_OPENGL | SDL_HWSURFACE))) &lt;br /&gt;
		{&lt;br /&gt;
			std::cerr &amp;lt;&amp;lt; &amp;quot;SDL_SetVideoMode failed: &amp;quot; &amp;lt;&amp;lt; SDL_GetError() &amp;lt;&amp;lt; std::endl;&lt;br /&gt;
			SDL_Quit();&lt;br /&gt;
			return 0;&lt;br /&gt;
		}&lt;br /&gt;
		SDL_WM_SetCaption(&amp;quot;SDL App&amp;quot;,NULL);&lt;br /&gt;
	}&lt;br /&gt;
	// check if stereo rendering is enabled&lt;br /&gt;
	int ga = 0;&lt;br /&gt;
	if (SDL_GL_GetAttribute(SDL_GL_STEREO, &amp;amp;ga) == 0) {&lt;br /&gt;
		if (ga == 0)&lt;br /&gt;
			std::cout&amp;lt;&amp;lt;&amp;quot;No stereo rendering available.&amp;quot;&amp;lt;&amp;lt;std::endl;&lt;br /&gt;
		else&lt;br /&gt;
			std::cout&amp;lt;&amp;lt;&amp;quot;Stereo rendering enabled!.&amp;quot;&amp;lt;&amp;lt;std::endl;&lt;br /&gt;
	}&lt;br /&gt;
	return true;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
This will also work with GLFW. Just call this line before opening your GLFW window.&lt;br /&gt;
{{CppSourceCode|&lt;br /&gt;
description= GLFW stereo flag| &lt;br /&gt;
code=&lt;br /&gt;
&amp;lt;source lang=&amp;quot;cpp&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
       glfwOpenWindowHint( GLFW_STEREO, GL_TRUE );&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Render the scene ==&lt;br /&gt;
Now we need to calculate the eye offset and render the scene twice for both eyes. This is done by switching the Horde3D render buffer for each eye, moving the camera to the desired eye offset and render the scene to the specified buffer. Again, this will only be done if stereo rendering was enabled successfully.&lt;br /&gt;
&lt;br /&gt;
We will calculate the eye offset by simply &amp;quot;strafing&amp;quot; the camera from its original position slightly to the left and right and rotating it inwards. This example has some keys assigned to adjust the eye offset and strabismus (&amp;quot;cross-eyedness&amp;quot;) on the fly. In normal (non-stereo) mode we can switch between the eyes to check the camera position even if stereo rendering is not available.&lt;br /&gt;
{{CppSourceCode|&lt;br /&gt;
description= Render the scene (app.cpp)| &lt;br /&gt;
code=&lt;br /&gt;
&amp;lt;source lang=&amp;quot;cpp&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
float eyOffsetFactor = 3.0f;&lt;br /&gt;
float strabismus = 3.0f;&lt;br /&gt;
int eye = 0;&lt;br /&gt;
void Application::mainLoop( int fps )&lt;br /&gt;
{&lt;br /&gt;
	_curFPS = fps;&lt;br /&gt;
	keyHandler();&lt;br /&gt;
	if(! _freeze )&lt;br /&gt;
	{&lt;br /&gt;
		// calculate eye-offsets for stereo rendering&lt;br /&gt;
		float xEyeOffset = eyOffsetFactor*sinf( degToRad( _ry + 90 ) );&lt;br /&gt;
		float zEyeOffset = eyOffsetFactor*cosf( degToRad( _ry + 90 ) );&lt;br /&gt;
&lt;br /&gt;
		// ........ &lt;br /&gt;
&lt;br /&gt;
		// Render scene&lt;br /&gt;
		// render stereo&lt;br /&gt;
		int ga = 0;&lt;br /&gt;
		if (SDL_GL_GetAttribute(SDL_GL_STEREO, &amp;amp;ga) == 0 &amp;amp;&amp;amp; ga == 1) {&lt;br /&gt;
			Horde3D::setNodeParami(_cam, CameraNodeParams::OutputBufferIndex, 0);&lt;br /&gt;
			Horde3D::setNodeTransform( _cam, _x-xEyeOffset, _y, _z-zEyeOffset, _rx ,_ry-strabismus, 0, 1, 1, 1 );&lt;br /&gt;
			Horde3D::render( _cam );&lt;br /&gt;
			Horde3D::finalizeFrame();  // comment this line if you are using Horde3D 1.0.0 beta 2&lt;br /&gt;
			Horde3D::setNodeParami(_cam, CameraNodeParams::OutputBufferIndex, 1);&lt;br /&gt;
			Horde3D::setNodeTransform( _cam, _x+xEyeOffset, _y, _z+zEyeOffset, _rx ,_ry+strabismus, 0, 1, 1, 1 );&lt;br /&gt;
			Horde3D::render( _cam );&lt;br /&gt;
			Horde3D::finalizeFrame(); // comment this line if you are using Horde3D 1.0.0 beta 2&lt;br /&gt;
		}&lt;br /&gt;
		else { // non stereo&lt;br /&gt;
			// Set camera parameters&lt;br /&gt;
			if (eye == 1)  // left eye&lt;br /&gt;
				Horde3D::setNodeTransform( _cam, _x-xEyeOffset, _y, _z-zEyeOffset, _rx ,_ry-strabismus, 0, 1, 1, 1 );&lt;br /&gt;
			else if (eye == 2)  // right eye&lt;br /&gt;
				Horde3D::setNodeTransform( _cam, _x+xEyeOffset, _y, _z+zEyeOffset, _rx ,_ry+strabismus, 0, 1, 1, 1 );&lt;br /&gt;
			else if(eye == 0)  // normal camera (centered)&lt;br /&gt;
				Horde3D::setNodeTransform( _cam, _x, _y, _z, _rx ,_ry, 0, 1, 1, 1 );&lt;br /&gt;
			Horde3D::render( _cam );&lt;br /&gt;
			Horde3D::finalizeFrame();  // comment this line if you are using Horde3D 1.0.0 beta 2&lt;br /&gt;
		}&lt;br /&gt;
		// Remove all overlays&lt;br /&gt;
		Horde3D::clearOverlays();&lt;br /&gt;
	&lt;br /&gt;
		// Write all mesages to log file&lt;br /&gt;
		Horde3DUtils::dumpMessages();&lt;br /&gt;
&lt;br /&gt;
		SDL_GL_SwapBuffers();&lt;br /&gt;
	}&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void Application::keyPressEvent( SDLKey key )&lt;br /&gt;
{&lt;br /&gt;
	// add more key events here...&lt;br /&gt;
&lt;br /&gt;
	// switch between eyes (0: normal/center, 1: left eye, 2: right eye)&lt;br /&gt;
	if( key == SDLK_F5 )	{// F5&lt;br /&gt;
		++eye;&lt;br /&gt;
		if (eye &amp;gt;= 3)&lt;br /&gt;
			eye = 0;&lt;br /&gt;
		std::cout&amp;lt;&amp;lt;&amp;quot;eye: &amp;quot;&amp;lt;&amp;lt;eye&amp;lt;&amp;lt;std::endl;&lt;br /&gt;
	}&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void Application::keyHandler()&lt;br /&gt;
{&lt;br /&gt;
	// add more keys if desired...&lt;br /&gt;
&lt;br /&gt;
	// adjust strabismus (cross eyedness)&lt;br /&gt;
	if(_keys[SDLK_0])&lt;br /&gt;
	{&lt;br /&gt;
		if (strabismus &amp;lt; 45)&lt;br /&gt;
			strabismus += 0.3f;&lt;br /&gt;
	}&lt;br /&gt;
	if(_keys[SDLK_9])&lt;br /&gt;
	{&lt;br /&gt;
		if (strabismus &amp;gt; 0)&lt;br /&gt;
			strabismus -= 0.3f;&lt;br /&gt;
	}&lt;br /&gt;
	// adjust eye offset&lt;br /&gt;
	if(_keys[SDLK_8])&lt;br /&gt;
	{&lt;br /&gt;
		eyeOffset += 0.3f;&lt;br /&gt;
	}&lt;br /&gt;
	if(_keys[SDLK_7])&lt;br /&gt;
	{&lt;br /&gt;
		if (eyeOffset &amp;gt; 0) {&lt;br /&gt;
			eyeOffset -= 0.3f;&lt;br /&gt;
		}&lt;br /&gt;
	}&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
}}&lt;/div&gt;</summary>
		<author><name>Wakko</name></author>	</entry>

	<entry>
		<id>http://horde3d.org/wiki/index.php?title=Tutorial_-_Stereo_rendering&amp;diff=517</id>
		<title>Tutorial - Stereo rendering</title>
		<link rel="alternate" type="text/html" href="http://horde3d.org/wiki/index.php?title=Tutorial_-_Stereo_rendering&amp;diff=517"/>
				<updated>2009-07-11T11:59:53Z</updated>
		
		<summary type="html">&lt;p&gt;Wakko: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;'''In this tutorial I will describe how to perform quadbuffered stereo rendering with Horde3D. This explicitly requires a graphics card that supports quad-buffering, i.e. rendering to two different output devices(Nvidia Quadro or ATI/AMD FireGL). This has been tested with a stereo projection system and polarization glasses.'''&lt;br /&gt;
&lt;br /&gt;
To do this we need to render our scene from two different points of view(left and right eye) and send each frame to the corresponding output device.&lt;br /&gt;
&lt;br /&gt;
[http://www.gali-3d.com/archive/articles/StereoOpenGL/StereoscopicOpenGLTutorial.php Stereoscopic OpenGL Tutorial]&lt;br /&gt;
&lt;br /&gt;
[http://www.orthostereo.com/geometryopengl.html Stereoscopic Geometry in OpenGL]&lt;br /&gt;
In this tutorial we will only use an asymmetric frustum.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Enable quadbuffering ==&lt;br /&gt;
First of all we need to tell our graphics card to enable quadbuffering if available. The following code shows how to do this using SDL. We will try to enable stereo rendering by default but it will fall back to non-stereo if the graphics card does not have quadbuffering capabilities. We will enable stereo rendering only in fullscreen mode. &lt;br /&gt;
{{CppSourceCode|&lt;br /&gt;
description= SDL Stereo Setup (main.cpp)| &lt;br /&gt;
code=&lt;br /&gt;
&amp;lt;source lang=&amp;quot;cpp&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
bool setupWindow( int width, int height, bool fullscreen )&lt;br /&gt;
{&lt;br /&gt;
	const SDL_VideoInfo* videoInfo = SDL_GetVideoInfo();&lt;br /&gt;
	SDL_Surface* surface;&lt;br /&gt;
&lt;br /&gt;
	appWidth = fullscreen ? videoInfo-&amp;gt;current_w : width;&lt;br /&gt;
	appHeight = fullscreen ? videoInfo-&amp;gt;current_h : height;&lt;br /&gt;
&lt;br /&gt;
	const bool fullscreen = true;&lt;br /&gt;
&lt;br /&gt;
	if(fullscreen)&lt;br /&gt;
	{&lt;br /&gt;
		// enable stereo if possible (only in fullscreen mode)&lt;br /&gt;
		if ( SDL_GL_SetAttribute(SDL_GL_STEREO, 1) == 0) {&lt;br /&gt;
			std::cout&amp;lt;&amp;lt;&amp;quot;Stereo flag set!&amp;quot;&amp;lt;&amp;lt;std::endl;&lt;br /&gt;
		}&lt;br /&gt;
		// Try to initialize the SDL_Surface with Stereo enabled&lt;br /&gt;
		if (!(surface =  SDL_SetVideoMode(appWidth,appHeight,32,SDL_OPENGL | SDL_FULLSCREEN | SDL_HWSURFACE))) &lt;br /&gt;
		{&lt;br /&gt;
			// if initialization with stereo enabled failed disable the stereo flag and retry&lt;br /&gt;
			std::cerr &amp;lt;&amp;lt; &amp;quot;STEREO initialization failed! Restarting...&amp;quot;&amp;lt;&amp;lt; std::endl;&lt;br /&gt;
			SDL_GL_SetAttribute(SDL_GL_STEREO, 0);&lt;br /&gt;
			if (!(surface =  SDL_SetVideoMode(appWidth, appHeight, 32, SDL_OPENGL | SDL_FULLSCREEN | SDL_HWSURFACE))) {&lt;br /&gt;
			     std::cerr &amp;lt;&amp;lt; &amp;quot;SDL_SetVideoMode failed: &amp;quot; &amp;lt;&amp;lt; SDL_GetError() &amp;lt;&amp;lt; std::endl;&lt;br /&gt;
			     SDL_Quit();&lt;br /&gt;
			     return 0;&lt;br /&gt;
			}&lt;br /&gt;
		}&lt;br /&gt;
	}else // windowed&lt;br /&gt;
	{	&lt;br /&gt;
		if (!(surface = SDL_SetVideoMode(appWidth,appHeight,32,SDL_OPENGL | SDL_HWSURFACE))) &lt;br /&gt;
		{&lt;br /&gt;
			std::cerr &amp;lt;&amp;lt; &amp;quot;SDL_SetVideoMode failed: &amp;quot; &amp;lt;&amp;lt; SDL_GetError() &amp;lt;&amp;lt; std::endl;&lt;br /&gt;
			SDL_Quit();&lt;br /&gt;
			return 0;&lt;br /&gt;
		}&lt;br /&gt;
		SDL_WM_SetCaption(&amp;quot;SDL App&amp;quot;,NULL);&lt;br /&gt;
	}&lt;br /&gt;
	// check if stereo rendering is enabled&lt;br /&gt;
	int ga = 0;&lt;br /&gt;
	if (SDL_GL_GetAttribute(SDL_GL_STEREO, &amp;amp;ga) == 0) {&lt;br /&gt;
		if (ga == 0)&lt;br /&gt;
			std::cout&amp;lt;&amp;lt;&amp;quot;No stereo rendering available.&amp;quot;&amp;lt;&amp;lt;std::endl;&lt;br /&gt;
		else&lt;br /&gt;
			std::cout&amp;lt;&amp;lt;&amp;quot;Stereo rendering enabled!.&amp;quot;&amp;lt;&amp;lt;std::endl;&lt;br /&gt;
	}&lt;br /&gt;
	return true;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
This will also work with GLFW. Just call this line before opening your GLFW window.&lt;br /&gt;
{{CppSourceCode|&lt;br /&gt;
description= GLFW stereo flag| &lt;br /&gt;
code=&lt;br /&gt;
&amp;lt;source lang=&amp;quot;cpp&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
       glfwOpenWindowHint( GLFW_STEREO, GL_TRUE );&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Render the scene ==&lt;br /&gt;
Now we need to calculate the eye offset and render the scene twice for both eyes. This is done by switching the Horde3D render buffer for each eye, moving the camera to the desired eye offset and render the scene to the specified buffer. Again, this will only be done if stereo rendering was enabled successfully.&lt;br /&gt;
&lt;br /&gt;
We will calculate the eye offset by simply &amp;quot;strafing&amp;quot; the camera from its original position slightly to the left and right and rotating it inwards. This example has some keys assigned to adjust the eye offset and strabismus (&amp;quot;cross-eyedness&amp;quot;) on the fly. In normal (non-stereo) mode we can switch between the eyes to check the camera position even if stereo rendering is not available.&lt;br /&gt;
{{CppSourceCode|&lt;br /&gt;
description= Render the scene (app.cpp)| &lt;br /&gt;
code=&lt;br /&gt;
&amp;lt;source lang=&amp;quot;cpp&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
float eyOffsetFactor = 3.0f;&lt;br /&gt;
float strabismus = 3.0f;&lt;br /&gt;
int eye = 0;&lt;br /&gt;
void Application::mainLoop( int fps )&lt;br /&gt;
{&lt;br /&gt;
	_curFPS = fps;&lt;br /&gt;
	keyHandler();&lt;br /&gt;
	if(! _freeze )&lt;br /&gt;
	{&lt;br /&gt;
		// calculate eye-offsets for stereo rendering&lt;br /&gt;
		float xEyeOffset = eyOffsetFactor*sinf( degToRad( _ry + 90 ) );&lt;br /&gt;
		float zEyeOffset = eyOffsetFactor*cosf( degToRad( _ry + 90 ) );&lt;br /&gt;
&lt;br /&gt;
		// ........ &lt;br /&gt;
&lt;br /&gt;
		// Render scene&lt;br /&gt;
		// render stereo&lt;br /&gt;
		int ga = 0;&lt;br /&gt;
		if (SDL_GL_GetAttribute(SDL_GL_STEREO, &amp;amp;ga) == 0 &amp;amp;&amp;amp; ga == 1) {&lt;br /&gt;
			Horde3D::setNodeParami(_cam, CameraNodeParams::OutputBufferIndex, 0);&lt;br /&gt;
			Horde3D::setNodeTransform( _cam, _x-xEyeOffset, _y, _z-zEyeOffset, _rx ,_ry-strabismus, 0, 1, 1, 1 );&lt;br /&gt;
			Horde3D::render( _cam );&lt;br /&gt;
			Horde3D::finalizeFrame();  // comment this line if you are using Horde3D 1.0.0 beta 2&lt;br /&gt;
			Horde3D::setNodeParami(_cam, CameraNodeParams::OutputBufferIndex, 1);&lt;br /&gt;
			Horde3D::setNodeTransform( _cam, _x+xEyeOffset, _y, _z+zEyeOffset, _rx ,_ry+strabismus, 0, 1, 1, 1 );&lt;br /&gt;
			Horde3D::render( _cam );&lt;br /&gt;
			Horde3D::finalizeFrame(); // comment this line if you are using Horde3D 1.0.0 beta 2&lt;br /&gt;
		}&lt;br /&gt;
		else { // non stereo&lt;br /&gt;
			// Set camera parameters&lt;br /&gt;
			if (eye == 1)  // left eye&lt;br /&gt;
				Horde3D::setNodeTransform( _cam, _x-xEyeOffset, _y, _z-zEyeOffset, _rx ,_ry-strabismus, 0, 1, 1, 1 );&lt;br /&gt;
			else if (eye == 2)  // right eye&lt;br /&gt;
				Horde3D::setNodeTransform( _cam, _x+xEyeOffset, _y, _z+zEyeOffset, _rx ,_ry+strabismus, 0, 1, 1, 1 );&lt;br /&gt;
			else if(eye == 0)  // normal camera (centered)&lt;br /&gt;
				Horde3D::setNodeTransform( _cam, _x, _y, _z, _rx ,_ry, 0, 1, 1, 1 );&lt;br /&gt;
			Horde3D::render( _cam );&lt;br /&gt;
			Horde3D::finalizeFrame();  // comment this line if you are using Horde3D 1.0.0 beta 2&lt;br /&gt;
		}&lt;br /&gt;
		// Remove all overlays&lt;br /&gt;
		Horde3D::clearOverlays();&lt;br /&gt;
	&lt;br /&gt;
		// Write all mesages to log file&lt;br /&gt;
		Horde3DUtils::dumpMessages();&lt;br /&gt;
&lt;br /&gt;
		SDL_GL_SwapBuffers();&lt;br /&gt;
	}&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void Application::keyPressEvent( SDLKey key )&lt;br /&gt;
{&lt;br /&gt;
	// add more key events here...&lt;br /&gt;
&lt;br /&gt;
	// switch between eyes (0: normal/center, 1: left eye, 2: right eye)&lt;br /&gt;
	if( key == SDLK_F5 )	{// F5&lt;br /&gt;
		++eye;&lt;br /&gt;
		if (eye &amp;gt;= 3)&lt;br /&gt;
			eye = 0;&lt;br /&gt;
		std::cout&amp;lt;&amp;lt;&amp;quot;eye: &amp;quot;&amp;lt;&amp;lt;eye&amp;lt;&amp;lt;std::endl;&lt;br /&gt;
	}&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void Application::keyHandler()&lt;br /&gt;
{&lt;br /&gt;
	// add more keys if desired...&lt;br /&gt;
&lt;br /&gt;
	// adjust strabismus (cross eyedness)&lt;br /&gt;
	if(_keys[SDLK_0])&lt;br /&gt;
	{&lt;br /&gt;
		if (strabismus &amp;lt; 45)&lt;br /&gt;
			strabismus += 0.3f;&lt;br /&gt;
	}&lt;br /&gt;
	if(_keys[SDLK_9])&lt;br /&gt;
	{&lt;br /&gt;
		if (strabismus &amp;gt; 0)&lt;br /&gt;
			strabismus -= 0.3f;&lt;br /&gt;
	}&lt;br /&gt;
	// adjust eye offset&lt;br /&gt;
	if(_keys[SDLK_8])&lt;br /&gt;
	{&lt;br /&gt;
		eyeOffset += 0.3f;&lt;br /&gt;
	}&lt;br /&gt;
	if(_keys[SDLK_7])&lt;br /&gt;
	{&lt;br /&gt;
		if (eyeOffset &amp;gt; 0) {&lt;br /&gt;
			eyeOffset -= 0.3f;&lt;br /&gt;
		}&lt;br /&gt;
	}&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
}}&lt;/div&gt;</summary>
		<author><name>Wakko</name></author>	</entry>

	<entry>
		<id>http://horde3d.org/wiki/index.php?title=Tutorial_-_Stereo_rendering&amp;diff=516</id>
		<title>Tutorial - Stereo rendering</title>
		<link rel="alternate" type="text/html" href="http://horde3d.org/wiki/index.php?title=Tutorial_-_Stereo_rendering&amp;diff=516"/>
				<updated>2009-07-11T11:52:50Z</updated>
		
		<summary type="html">&lt;p&gt;Wakko: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;'''In this tutorial I will describe how to perform quadbuffered stereo rendering with Horde3D. This explicitly requires a graphics card that supports quad-buffering, i.e. rendering to two different output devices(Nvidia Quadro or ATI/AMD FireGL). This has been tested with a stereo projection system and polarization glasses.'''&lt;br /&gt;
&lt;br /&gt;
To do this we need to render our scene from two different points of view(left and right eye) and send each frame to the corresponding output device.&lt;br /&gt;
&lt;br /&gt;
[http://www.gali-3d.com/archive/articles/StereoOpenGL/StereoscopicOpenGLTutorial.php Stereoscopic OpenGL Tutorial]&lt;br /&gt;
&lt;br /&gt;
[http://www.orthostereo.com/geometryopengl.html Stereoscopic Geometry in OpenGL]&lt;br /&gt;
In this tutorial we will only use an asymmetric frustum.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Enable quadbuffering ==&lt;br /&gt;
First of all we need to tell our graphics card to enable quadbuffering if available. The following code shows how to do this using SDL. We will try to enable stereo rendering by default but it will fall back to non-stereo if the graphics card does not have quadbuffering capabilities. We will enable stereo rendering only in fullscreen mode. &lt;br /&gt;
{{CppSourceCode|&lt;br /&gt;
description= SDL Stereo Setup (main.cpp)| &lt;br /&gt;
code=&lt;br /&gt;
&amp;lt;source lang=&amp;quot;cpp&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
bool setupWindow( int width, int height, bool fullscreen )&lt;br /&gt;
{&lt;br /&gt;
	const SDL_VideoInfo* videoInfo = SDL_GetVideoInfo();&lt;br /&gt;
	SDL_Surface* surface;&lt;br /&gt;
&lt;br /&gt;
	appWidth = fullscreen ? videoInfo-&amp;gt;current_w : width;&lt;br /&gt;
	appHeight = fullscreen ? videoInfo-&amp;gt;current_h : height;&lt;br /&gt;
&lt;br /&gt;
	const bool fullscreen = true;&lt;br /&gt;
&lt;br /&gt;
	if(fullscreen)&lt;br /&gt;
	{&lt;br /&gt;
		// enable stereo if possible (only in fullscreen mode)&lt;br /&gt;
		if ( SDL_GL_SetAttribute(SDL_GL_STEREO, 1) == 0) {&lt;br /&gt;
			std::cout&amp;lt;&amp;lt;&amp;quot;Stereo flag set!&amp;quot;&amp;lt;&amp;lt;std::endl;&lt;br /&gt;
		}&lt;br /&gt;
		// Try to initialize the SDL_Surface with Stereo enabled&lt;br /&gt;
		if (!(surface =  SDL_SetVideoMode(appWidth,appHeight,32,SDL_OPENGL | SDL_FULLSCREEN | SDL_HWSURFACE))) &lt;br /&gt;
		{&lt;br /&gt;
			// if initialization with stereo enabled failed disable the stereo flag and retry&lt;br /&gt;
			std::cerr &amp;lt;&amp;lt; &amp;quot;STEREO initialization failed! Restarting...&amp;quot;&amp;lt;&amp;lt; std::endl;&lt;br /&gt;
			SDL_GL_SetAttribute(SDL_GL_STEREO, 0);&lt;br /&gt;
			if (!SDL_SetVideoMode(width, height, 32, SDL_OPENGL | SDL_FULLSCREEN | SDL_HWSURFACE)) {&lt;br /&gt;
			     std::cerr &amp;lt;&amp;lt; &amp;quot;SDL_SetVideoMode failed: &amp;quot; &amp;lt;&amp;lt; SDL_GetError() &amp;lt;&amp;lt; std::endl;&lt;br /&gt;
			     SDL_Quit();&lt;br /&gt;
			     return 0;&lt;br /&gt;
			}&lt;br /&gt;
		}&lt;br /&gt;
	}else // windowed&lt;br /&gt;
	{	&lt;br /&gt;
		if (!(surface = SDL_SetVideoMode(appWidth,appHeight,32,SDL_OPENGL | SDL_HWSURFACE))) &lt;br /&gt;
		{&lt;br /&gt;
			std::cerr &amp;lt;&amp;lt; &amp;quot;SDL_SetVideoMode failed: &amp;quot; &amp;lt;&amp;lt; SDL_GetError() &amp;lt;&amp;lt; std::endl;&lt;br /&gt;
			SDL_Quit();&lt;br /&gt;
			return 0;&lt;br /&gt;
		}&lt;br /&gt;
		SDL_WM_SetCaption(&amp;quot;SDL App&amp;quot;,NULL);&lt;br /&gt;
	}&lt;br /&gt;
	// check if stereo rendering is enabled&lt;br /&gt;
	int ga = 0;&lt;br /&gt;
	if (SDL_GL_GetAttribute(SDL_GL_STEREO, &amp;amp;ga) == 0) {&lt;br /&gt;
		if (ga == 0)&lt;br /&gt;
			std::cout&amp;lt;&amp;lt;&amp;quot;No stereo rendering available.&amp;quot;&amp;lt;&amp;lt;std::endl;&lt;br /&gt;
		else&lt;br /&gt;
			std::cout&amp;lt;&amp;lt;&amp;quot;Stereo rendering enabled!.&amp;quot;&amp;lt;&amp;lt;std::endl;&lt;br /&gt;
	}&lt;br /&gt;
	return true;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
This will also work with GLFW. Just call this line before opening your GLFW window.&lt;br /&gt;
{{CppSourceCode|&lt;br /&gt;
description= GLFW stereo flag| &lt;br /&gt;
code=&lt;br /&gt;
&amp;lt;source lang=&amp;quot;cpp&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
       glfwOpenWindowHint( GLFW_STEREO, GL_TRUE );&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Render the scene ==&lt;br /&gt;
Now we need to calculate the eye offset and render the scene twice for both eyes. This is done by switching the Horde3D render buffer for each eye, moving the camera to the desired eye offset and render the scene to the specified buffer. Again, this will only be done if stereo rendering was enabled successfully.&lt;br /&gt;
&lt;br /&gt;
We will calculate the eye offset by simply &amp;quot;strafing&amp;quot; the camera from its original position slightly to the left and right and rotating it inwards. This example has some keys assigned to adjust the eye offset and strabismus (&amp;quot;cross-eyedness&amp;quot;) on the fly. In normal (non-stereo) mode we can switch between the eyes to check if the camera position even if stereo rendering is not available.&lt;br /&gt;
{{CppSourceCode|&lt;br /&gt;
description= Render the scene (app.cpp)| &lt;br /&gt;
code=&lt;br /&gt;
&amp;lt;source lang=&amp;quot;cpp&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
float eyOffsetFactor = 3.0f;&lt;br /&gt;
float strabismus = 3.0f;&lt;br /&gt;
int eye = 0;&lt;br /&gt;
void Application::mainLoop( int fps )&lt;br /&gt;
{&lt;br /&gt;
	_curFPS = fps;&lt;br /&gt;
	keyHandler();&lt;br /&gt;
	if(! _freeze )&lt;br /&gt;
	{&lt;br /&gt;
		// calculate eye-offsets for stereo rendering&lt;br /&gt;
		float xEyeOffset = eyOffsetFactor*sinf( degToRad( _ry + 90 ) );&lt;br /&gt;
		float zEyeOffset = eyOffsetFactor*cosf( degToRad( _ry + 90 ) );&lt;br /&gt;
&lt;br /&gt;
		// ........ &lt;br /&gt;
&lt;br /&gt;
		// Render scene&lt;br /&gt;
		// render stereo&lt;br /&gt;
		int ga = 0;&lt;br /&gt;
		if (SDL_GL_GetAttribute(SDL_GL_STEREO, &amp;amp;ga) == 0 &amp;amp;&amp;amp; ga == 1) {&lt;br /&gt;
			Horde3D::setNodeParami(_cam, CameraNodeParams::OutputBufferIndex, 0);&lt;br /&gt;
			Horde3D::setNodeTransform( _cam, _x-xEyeOffset, _y, _z-zEyeOffset, _rx ,_ry-strabismus, 0, 1, 1, 1 );&lt;br /&gt;
			Horde3D::render( _cam );&lt;br /&gt;
			Horde3D::finalizeFrame();  // comment this line if you are using Horde3D 1.0.0 beta 2&lt;br /&gt;
			Horde3D::setNodeParami(_cam, CameraNodeParams::OutputBufferIndex, 1);&lt;br /&gt;
			Horde3D::setNodeTransform( _cam, _x+xEyeOffset, _y, _z+zEyeOffset, _rx ,_ry+strabismus, 0, 1, 1, 1 );&lt;br /&gt;
			Horde3D::render( _cam );&lt;br /&gt;
			Horde3D::finalizeFrame(); // comment this line if you are using Horde3D 1.0.0 beta 2&lt;br /&gt;
		}&lt;br /&gt;
		else { // non stereo&lt;br /&gt;
			// Set camera parameters&lt;br /&gt;
			if (eye == 1)  // left eye&lt;br /&gt;
				Horde3D::setNodeTransform( _cam, _x-xEyeOffset, _y, _z-zEyeOffset, _rx ,_ry-strabismus, 0, 1, 1, 1 );&lt;br /&gt;
			else if (eye == 2)  // right eye&lt;br /&gt;
				Horde3D::setNodeTransform( _cam, _x+xEyeOffset, _y, _z+zEyeOffset, _rx ,_ry+strabismus, 0, 1, 1, 1 );&lt;br /&gt;
			else if(eye == 0)  // normal camera (centered)&lt;br /&gt;
				Horde3D::setNodeTransform( _cam, _x, _y, _z, _rx ,_ry, 0, 1, 1, 1 );&lt;br /&gt;
			Horde3D::render( _cam );&lt;br /&gt;
			Horde3D::finalizeFrame();  // comment this line if you are using Horde3D 1.0.0 beta 2&lt;br /&gt;
		}&lt;br /&gt;
		// Remove all overlays&lt;br /&gt;
		Horde3D::clearOverlays();&lt;br /&gt;
	&lt;br /&gt;
		// Write all mesages to log file&lt;br /&gt;
		Horde3DUtils::dumpMessages();&lt;br /&gt;
&lt;br /&gt;
		SDL_GL_SwapBuffers();&lt;br /&gt;
	}&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void Application::keyPressEvent( SDLKey key )&lt;br /&gt;
{&lt;br /&gt;
	// add more key events here...&lt;br /&gt;
&lt;br /&gt;
	// switch between eyes (0: normal/center, 1: left eye, 2: right eye)&lt;br /&gt;
	if( key == SDLK_F5 )	{// F5&lt;br /&gt;
		++eye;&lt;br /&gt;
		if (eye &amp;gt;= 3)&lt;br /&gt;
			eye = 0;&lt;br /&gt;
		std::cout&amp;lt;&amp;lt;&amp;quot;eye: &amp;quot;&amp;lt;&amp;lt;eye&amp;lt;&amp;lt;std::endl;&lt;br /&gt;
	}&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void Application::keyHandler()&lt;br /&gt;
{&lt;br /&gt;
	// add more keys if desired...&lt;br /&gt;
&lt;br /&gt;
	// adjust strabismus (cross eyedness)&lt;br /&gt;
	if(_keys[SDLK_0])&lt;br /&gt;
	{&lt;br /&gt;
		if (strabismus &amp;lt; 45)&lt;br /&gt;
			strabismus += 0.3f;&lt;br /&gt;
	}&lt;br /&gt;
	if(_keys[SDLK_9])&lt;br /&gt;
	{&lt;br /&gt;
		if (strabismus &amp;gt; 0)&lt;br /&gt;
			strabismus -= 0.3f;&lt;br /&gt;
	}&lt;br /&gt;
	// adjust eye offset&lt;br /&gt;
	if(_keys[SDLK_8])&lt;br /&gt;
	{&lt;br /&gt;
		eyeOffset += 0.3f;&lt;br /&gt;
	}&lt;br /&gt;
	if(_keys[SDLK_7])&lt;br /&gt;
	{&lt;br /&gt;
		if (eyeOffset &amp;gt; 0) {&lt;br /&gt;
			eyeOffset -= 0.3f;&lt;br /&gt;
		}&lt;br /&gt;
	}&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
}}&lt;/div&gt;</summary>
		<author><name>Wakko</name></author>	</entry>

	<entry>
		<id>http://horde3d.org/wiki/index.php?title=Tutorial_-_Stereo_rendering&amp;diff=515</id>
		<title>Tutorial - Stereo rendering</title>
		<link rel="alternate" type="text/html" href="http://horde3d.org/wiki/index.php?title=Tutorial_-_Stereo_rendering&amp;diff=515"/>
				<updated>2009-07-11T11:42:11Z</updated>
		
		<summary type="html">&lt;p&gt;Wakko: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;'''In this tutorial I will describe how to perform quadbuffered stereo rendering with Horde3D. This explicitly requires a graphics card that supports quad-buffering, i.e. rendering to two different output devices(Nvidia Quadro or ATI/AMD FireGL). This has been tested with a stereo projection system and polarization glasses.'''&lt;br /&gt;
&lt;br /&gt;
To do this we need to render our scene from two different points of view(left and right eye) and send each frame to the corresponding output device.&lt;br /&gt;
&lt;br /&gt;
[http://www.gali-3d.com/archive/articles/StereoOpenGL/StereoscopicOpenGLTutorial.php Stereoscopic OpenGL Tutorial]&lt;br /&gt;
&lt;br /&gt;
[http://www.orthostereo.com/geometryopengl.html Stereoscopic Geometry in OpenGL]&lt;br /&gt;
In this tutorial we will only use an asymmetric frustum.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Enable quadbuffering ==&lt;br /&gt;
First of all we need to tell our graphics card to enable quadbuffering if available. The following code shows how to do this using SDL. We will try to enable stereo rendering by default but it will fall back to non-stereo if the graphics card does not have quadbuffering capabilities. We will enable stereo rendering only in fullscreen mode. &lt;br /&gt;
{{CppSourceCode|&lt;br /&gt;
description= SDL Stereo Setup (main.cpp)| &lt;br /&gt;
code=&lt;br /&gt;
&amp;lt;source lang=&amp;quot;cpp&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
bool setupWindow( int width, int height, bool fullscreen )&lt;br /&gt;
{&lt;br /&gt;
	const SDL_VideoInfo* videoInfo = SDL_GetVideoInfo();&lt;br /&gt;
	SDL_Surface* surface;&lt;br /&gt;
&lt;br /&gt;
	appWidth = fullscreen ? videoInfo-&amp;gt;current_w : width;&lt;br /&gt;
	appHeight = fullscreen ? videoInfo-&amp;gt;current_h : height;&lt;br /&gt;
&lt;br /&gt;
	const bool fullscreen = true;&lt;br /&gt;
&lt;br /&gt;
	if(fullscreen)&lt;br /&gt;
	{&lt;br /&gt;
		// enable stereo if possible (only in fullscreen mode)&lt;br /&gt;
		if ( SDL_GL_SetAttribute(SDL_GL_STEREO, 1) == 0) {&lt;br /&gt;
			std::cout&amp;lt;&amp;lt;&amp;quot;Stereo flag set!&amp;quot;&amp;lt;&amp;lt;std::endl;&lt;br /&gt;
		}&lt;br /&gt;
		// Try to initialize the SDL_Surface with Stereo enabled&lt;br /&gt;
		if (!(surface =  SDL_SetVideoMode(appWidth,appHeight,32,SDL_OPENGL | SDL_FULLSCREEN | SDL_HWSURFACE))) &lt;br /&gt;
		{&lt;br /&gt;
			// if initialization with stereo enabled failed disable the stereo flag and retry&lt;br /&gt;
			std::cerr &amp;lt;&amp;lt; &amp;quot;STEREO initialization failed! Restarting...&amp;quot;&amp;lt;&amp;lt; std::endl;&lt;br /&gt;
			SDL_GL_SetAttribute(SDL_GL_STEREO, 0);&lt;br /&gt;
			if (!SDL_SetVideoMode(width, height, 32, SDL_OPENGL | SDL_FULLSCREEN | SDL_HWSURFACE)) {&lt;br /&gt;
			     std::cerr &amp;lt;&amp;lt; &amp;quot;SDL_SetVideoMode failed: &amp;quot; &amp;lt;&amp;lt; SDL_GetError() &amp;lt;&amp;lt; std::endl;&lt;br /&gt;
			     SDL_Quit();&lt;br /&gt;
			     return 0;&lt;br /&gt;
			}&lt;br /&gt;
		}&lt;br /&gt;
	}else // windowed&lt;br /&gt;
	{	&lt;br /&gt;
		if (!(surface = SDL_SetVideoMode(appWidth,appHeight,32,SDL_OPENGL | SDL_HWSURFACE))) &lt;br /&gt;
		{&lt;br /&gt;
			std::cerr &amp;lt;&amp;lt; &amp;quot;SDL_SetVideoMode failed: &amp;quot; &amp;lt;&amp;lt; SDL_GetError() &amp;lt;&amp;lt; std::endl;&lt;br /&gt;
			SDL_Quit();&lt;br /&gt;
			return 0;&lt;br /&gt;
		}&lt;br /&gt;
		SDL_WM_SetCaption(&amp;quot;SDL App&amp;quot;,NULL);&lt;br /&gt;
	}&lt;br /&gt;
	// check if stereo rendering is enabled&lt;br /&gt;
	int ga = 0;&lt;br /&gt;
	if (SDL_GL_GetAttribute(SDL_GL_STEREO, &amp;amp;ga) == 0) {&lt;br /&gt;
		if (ga == 0)&lt;br /&gt;
			std::cout&amp;lt;&amp;lt;&amp;quot;No stereo rendering available.&amp;quot;&amp;lt;&amp;lt;std::endl;&lt;br /&gt;
		else&lt;br /&gt;
			std::cout&amp;lt;&amp;lt;&amp;quot;Stereo rendering enabled!.&amp;quot;&amp;lt;&amp;lt;std::endl;&lt;br /&gt;
	}&lt;br /&gt;
	return true;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
This will also work with GLFW.&lt;br /&gt;
{{CppSourceCode|&lt;br /&gt;
description= GLFW stereo flag| &lt;br /&gt;
code=&lt;br /&gt;
&amp;lt;source lang=&amp;quot;cpp&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
       glfwOpenWindowHint( GLFW_STEREO, GL_TRUE );&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Render the scene ==&lt;br /&gt;
Now we need to calculate the eye offset and render the scene twice for both eyes. This is done by switching the Horde3D render buffer for each eye, moving the camera to the desired eye offset and render the scene to the specified buffer. Again, this will only be done if stereo rendering was enabled successfully.&lt;br /&gt;
&lt;br /&gt;
We will calculate the eye offset by simply &amp;quot;strafing&amp;quot; the camera from its original position slightly to the left and right and rotating it inwards. This example has some keys assigned to adjust the eye offset and strabismus (&amp;quot;cross-eyedness&amp;quot;) on the fly. In normal (non-stereo) mode we can switch between the eyes to check if the camera position even if stereo rendering is not available.&lt;br /&gt;
{{CppSourceCode|&lt;br /&gt;
description= Render the scene (app.cpp)| &lt;br /&gt;
code=&lt;br /&gt;
&amp;lt;source lang=&amp;quot;cpp&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
float eyOffsetFactor = 3.0f;&lt;br /&gt;
float strabismus = 3.0f;&lt;br /&gt;
int eye = 0;&lt;br /&gt;
void Application::mainLoop( int fps )&lt;br /&gt;
{&lt;br /&gt;
	_curFPS = fps;&lt;br /&gt;
	keyHandler();&lt;br /&gt;
	if(! _freeze )&lt;br /&gt;
	{&lt;br /&gt;
		// calculate eye-offsets for stereo rendering&lt;br /&gt;
		float xEyeOffset = eyOffsetFactor*sinf( degToRad( _ry + 90 ) );&lt;br /&gt;
		float zEyeOffset = eyOffsetFactor*cosf( degToRad( _ry + 90 ) );&lt;br /&gt;
&lt;br /&gt;
		// ........ &lt;br /&gt;
&lt;br /&gt;
		// Render scene&lt;br /&gt;
		// render stereo&lt;br /&gt;
		int ga = 0;&lt;br /&gt;
		if (SDL_GL_GetAttribute(SDL_GL_STEREO, &amp;amp;ga) == 0 &amp;amp;&amp;amp; ga == 1) {&lt;br /&gt;
			Horde3D::setNodeParami(_cam, CameraNodeParams::OutputBufferIndex, 0);&lt;br /&gt;
			Horde3D::setNodeTransform( _cam, _x-xEyeOffset, _y, _z-zEyeOffset, _rx ,_ry-strabismus, 0, 1, 1, 1 );&lt;br /&gt;
			Horde3D::render( _cam );&lt;br /&gt;
			Horde3D::finalizeFrame();  // comment this line if you are using Horde3D 1.0.0 beta 2&lt;br /&gt;
			Horde3D::setNodeParami(_cam, CameraNodeParams::OutputBufferIndex, 1);&lt;br /&gt;
			Horde3D::setNodeTransform( _cam, _x+xEyeOffset, _y, _z+zEyeOffset, _rx ,_ry+strabismus, 0, 1, 1, 1 );&lt;br /&gt;
			Horde3D::render( _cam );&lt;br /&gt;
			Horde3D::finalizeFrame(); // comment this line if you are using Horde3D 1.0.0 beta 2&lt;br /&gt;
		}&lt;br /&gt;
		else { // non stereo&lt;br /&gt;
			// Set camera parameters&lt;br /&gt;
			if (eye == 1)  // left eye&lt;br /&gt;
				Horde3D::setNodeTransform( _cam, _x-xEyeOffset, _y, _z-zEyeOffset, _rx ,_ry-strabismus, 0, 1, 1, 1 );&lt;br /&gt;
			else if (eye == 2)  // right eye&lt;br /&gt;
				Horde3D::setNodeTransform( _cam, _x+xEyeOffset, _y, _z+zEyeOffset, _rx ,_ry+strabismus, 0, 1, 1, 1 );&lt;br /&gt;
			else if(eye == 0)  // normal camera (centered)&lt;br /&gt;
				Horde3D::setNodeTransform( _cam, _x, _y, _z, _rx ,_ry, 0, 1, 1, 1 );&lt;br /&gt;
			Horde3D::render( _cam );&lt;br /&gt;
			Horde3D::finalizeFrame();  // comment this line if you are using Horde3D 1.0.0 beta 2&lt;br /&gt;
		}&lt;br /&gt;
		// Remove all overlays&lt;br /&gt;
		Horde3D::clearOverlays();&lt;br /&gt;
	&lt;br /&gt;
		// Write all mesages to log file&lt;br /&gt;
		Horde3DUtils::dumpMessages();&lt;br /&gt;
&lt;br /&gt;
		SDL_GL_SwapBuffers();&lt;br /&gt;
	}&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void Application::keyPressEvent( SDLKey key )&lt;br /&gt;
{&lt;br /&gt;
	// add more key events here...&lt;br /&gt;
&lt;br /&gt;
	// switch between eyes (0: normal/center, 1: left eye, 2: right eye)&lt;br /&gt;
	if( key == SDLK_F5 )	{// F5&lt;br /&gt;
		++eye;&lt;br /&gt;
		if (eye &amp;gt;= 3)&lt;br /&gt;
			eye = 0;&lt;br /&gt;
		std::cout&amp;lt;&amp;lt;&amp;quot;eye: &amp;quot;&amp;lt;&amp;lt;eye&amp;lt;&amp;lt;std::endl;&lt;br /&gt;
	}&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void Application::keyHandler()&lt;br /&gt;
{&lt;br /&gt;
	// add more keys if desired...&lt;br /&gt;
&lt;br /&gt;
	// adjust strabismus (cross eyedness)&lt;br /&gt;
	if(_keys[SDLK_0])&lt;br /&gt;
	{&lt;br /&gt;
		if (strabismus &amp;lt; 45)&lt;br /&gt;
			strabismus += 0.3f;&lt;br /&gt;
	}&lt;br /&gt;
	if(_keys[SDLK_9])&lt;br /&gt;
	{&lt;br /&gt;
		if (strabismus &amp;gt; 0)&lt;br /&gt;
			strabismus -= 0.3f;&lt;br /&gt;
	}&lt;br /&gt;
	// adjust eye offset&lt;br /&gt;
	if(_keys[SDLK_8])&lt;br /&gt;
	{&lt;br /&gt;
		eyeOffset += 0.3f;&lt;br /&gt;
	}&lt;br /&gt;
	if(_keys[SDLK_7])&lt;br /&gt;
	{&lt;br /&gt;
		if (eyeOffset &amp;gt; 0) {&lt;br /&gt;
			eyeOffset -= 0.3f;&lt;br /&gt;
		}&lt;br /&gt;
	}&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
}}&lt;/div&gt;</summary>
		<author><name>Wakko</name></author>	</entry>

	<entry>
		<id>http://horde3d.org/wiki/index.php?title=Tutorial_-_Stereo_rendering&amp;diff=514</id>
		<title>Tutorial - Stereo rendering</title>
		<link rel="alternate" type="text/html" href="http://horde3d.org/wiki/index.php?title=Tutorial_-_Stereo_rendering&amp;diff=514"/>
				<updated>2009-07-11T11:39:18Z</updated>
		
		<summary type="html">&lt;p&gt;Wakko: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;'''In this tutorial I will describe how to perform quadbuffered stereo rendering with Horde3D. This explicitly requires a graphics card that supports quad-buffering, i.e. rendering to two different output devices(Nvidia Quadro or ATI/AMD FireGL). This has been tested with a stereo projection system and polarization glasses.'''&lt;br /&gt;
&lt;br /&gt;
To do this we need to render our scene from two different points of view(left and right eye) and send each frame to the corresponding output device.&lt;br /&gt;
&lt;br /&gt;
[http://www.gali-3d.com/archive/articles/StereoOpenGL/StereoscopicOpenGLTutorial.php Stereoscopic OpenGL Tutorial]&lt;br /&gt;
&lt;br /&gt;
[http://www.orthostereo.com/geometryopengl.html Stereoscopic Geometry in OpenGL]&lt;br /&gt;
In this tutorial we will only use an asymmetric frustum.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Enable quadbuffering ==&lt;br /&gt;
First of all we need to tell our graphics card to enable quadbuffering if available. The following code shows how to do this using SDL. We will try to enable stereo rendering by default but it will fall back to non-stereo if the graphics card does not have quadbuffering capabilities. We will enable stereo rendering only in fullscreen mode. &lt;br /&gt;
{{CppSourceCode|&lt;br /&gt;
description= SDL Stereo Setup (main.cpp)| &lt;br /&gt;
code=&lt;br /&gt;
&amp;lt;source lang=&amp;quot;cpp&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
bool setupWindow( int width, int height, bool fullscreen )&lt;br /&gt;
{&lt;br /&gt;
	const SDL_VideoInfo* videoInfo = SDL_GetVideoInfo();&lt;br /&gt;
	SDL_Surface* surface;&lt;br /&gt;
&lt;br /&gt;
	appWidth = fullscreen ? videoInfo-&amp;gt;current_w : width;&lt;br /&gt;
	appHeight = fullscreen ? videoInfo-&amp;gt;current_h : height;&lt;br /&gt;
&lt;br /&gt;
	const bool fullscreen = true;&lt;br /&gt;
&lt;br /&gt;
	if(fullscreen)&lt;br /&gt;
	{&lt;br /&gt;
		// enable stereo if possible (only in fullscreen mode)&lt;br /&gt;
		if ( SDL_GL_SetAttribute(SDL_GL_STEREO, 1) == 0) {&lt;br /&gt;
			std::cout&amp;lt;&amp;lt;&amp;quot;Stereo flag set!&amp;quot;&amp;lt;&amp;lt;std::endl;&lt;br /&gt;
		}&lt;br /&gt;
		// Try to initialize the SDL_Surface with Stereo enabled&lt;br /&gt;
		if (!(surface =  SDL_SetVideoMode(appWidth,appHeight,32,SDL_OPENGL | SDL_FULLSCREEN | SDL_HWSURFACE))) &lt;br /&gt;
		{&lt;br /&gt;
			// if initialization with stereo enabled failed disable the stereo flag and retry&lt;br /&gt;
			std::cerr &amp;lt;&amp;lt; &amp;quot;STEREO initialization failed! Restarting...&amp;quot;&amp;lt;&amp;lt; std::endl;&lt;br /&gt;
			SDL_GL_SetAttribute(SDL_GL_STEREO, 0);&lt;br /&gt;
			if (!SDL_SetVideoMode(width, height, 32, SDL_OPENGL | SDL_FULLSCREEN | SDL_HWSURFACE)) {&lt;br /&gt;
			     std::cerr &amp;lt;&amp;lt; &amp;quot;SDL_SetVideoMode failed: &amp;quot; &amp;lt;&amp;lt; SDL_GetError() &amp;lt;&amp;lt; std::endl;&lt;br /&gt;
			     SDL_Quit();&lt;br /&gt;
			     return 0;&lt;br /&gt;
			}&lt;br /&gt;
		}&lt;br /&gt;
	}else // windowed&lt;br /&gt;
	{	&lt;br /&gt;
		if (!(surface = SDL_SetVideoMode(appWidth,appHeight,32,SDL_OPENGL | SDL_HWSURFACE))) &lt;br /&gt;
		{&lt;br /&gt;
			std::cerr &amp;lt;&amp;lt; &amp;quot;SDL_SetVideoMode failed: &amp;quot; &amp;lt;&amp;lt; SDL_GetError() &amp;lt;&amp;lt; std::endl;&lt;br /&gt;
			SDL_Quit();&lt;br /&gt;
			return 0;&lt;br /&gt;
		}&lt;br /&gt;
		SDL_WM_SetCaption(&amp;quot;SDL App&amp;quot;,NULL);&lt;br /&gt;
	}&lt;br /&gt;
	// check if stereo rendering is enabled&lt;br /&gt;
	int ga = 0;&lt;br /&gt;
	if (SDL_GL_GetAttribute(SDL_GL_STEREO, &amp;amp;ga) == 0) {&lt;br /&gt;
		if (ga == 0)&lt;br /&gt;
			std::cout&amp;lt;&amp;lt;&amp;quot;No stereo rendering available.&amp;quot;&amp;lt;&amp;lt;std::endl;&lt;br /&gt;
		else&lt;br /&gt;
			std::cout&amp;lt;&amp;lt;&amp;quot;Stereo rendering enabled!.&amp;quot;&amp;lt;&amp;lt;std::endl;&lt;br /&gt;
	}&lt;br /&gt;
	return true;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
This will also work with GLFW.&lt;br /&gt;
{{CppSourceCode|&lt;br /&gt;
description= GLFW stereo flag| &lt;br /&gt;
code=&lt;br /&gt;
&amp;lt;source lang=&amp;quot;cpp&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
       glfwOpenWindowHint( GLFW_STEREO, GL_TRUE );&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Render the scene ==&lt;br /&gt;
Now we need to calculate the eye offset and render the scene twice for both eyes. This is done by switching the Horde3D render buffer for each eye, moving the camera to the desired eye offset and render the scene to the specified buffer. Again, this will only be done if stereo rendering was enabled successfully.&lt;br /&gt;
&lt;br /&gt;
We will calculate the eye offset by simply &amp;quot;strafing&amp;quot; the camera from its original position slightly to the left and right and rotating it inwards. This example has some keys assigned to adjust the eye offset and strabismus (&amp;quot;cross-eyedness&amp;quot;) on the fly. In normal (non-stereo) mode we can switch between the eyes to check if the camera position even if stereo rendering is not available.&lt;br /&gt;
{{CppSourceCode|&lt;br /&gt;
description= Render the scene (app.cpp)| &lt;br /&gt;
code=&lt;br /&gt;
&amp;lt;source lang=&amp;quot;cpp&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
float eyOffsetFactor = 3.0f;&lt;br /&gt;
float strabismus = 3.0f;&lt;br /&gt;
int eye = 0;&lt;br /&gt;
void Application::mainLoop( int fps )&lt;br /&gt;
&lt;br /&gt;
{&lt;br /&gt;
&lt;br /&gt;
	_curFPS = fps;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
	keyHandler();&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
	if(! _freeze )&lt;br /&gt;
&lt;br /&gt;
	{&lt;br /&gt;
&lt;br /&gt;
		// calculate eye-offsets for stereo rendering&lt;br /&gt;
&lt;br /&gt;
		float xEyeOffset = eyOffsetFactor*sinf( degToRad( _ry + 90 ) );&lt;br /&gt;
&lt;br /&gt;
		float zEyeOffset = eyOffsetFactor*cosf( degToRad( _ry + 90 ) );&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
		// ........ &lt;br /&gt;
&lt;br /&gt;
		// Render scene&lt;br /&gt;
&lt;br /&gt;
		// render stereo&lt;br /&gt;
&lt;br /&gt;
		int ga = 0;&lt;br /&gt;
&lt;br /&gt;
		if (SDL_GL_GetAttribute(SDL_GL_STEREO, &amp;amp;ga) == 0 &amp;amp;&amp;amp; ga == 1) {&lt;br /&gt;
&lt;br /&gt;
			Horde3D::setNodeParami(_cam, CameraNodeParams::OutputBufferIndex, 0);&lt;br /&gt;
&lt;br /&gt;
			Horde3D::setNodeTransform( _cam, _x-xEyeOffset, _y, _z-zEyeOffset, _rx ,_ry-strabismus, 0, 1, 1, 1 );&lt;br /&gt;
			Horde3D::render( _cam );&lt;br /&gt;
&lt;br /&gt;
			Horde3D::finalizeFrame();&lt;br /&gt;
 // comment this line if you are using Horde3D 1.0.0 beta 2&lt;br /&gt;
			Horde3D::setNodeParami(_cam, CameraNodeParams::OutputBufferIndex, 1);&lt;br /&gt;
&lt;br /&gt;
			Horde3D::setNodeTransform( _cam, _x+xEyeOffset, _y, _z+zEyeOffset, _rx ,_ry+strabismus, 0, 1, 1, 1 );&lt;br /&gt;
			Horde3D::render( _cam );&lt;br /&gt;
&lt;br /&gt;
			Horde3D::finalizeFrame();&lt;br /&gt;
 // comment this line if you are using Horde3D 1.0.0 beta 2&lt;br /&gt;
		}&lt;br /&gt;
&lt;br /&gt;
		else {&lt;br /&gt;
&lt;br /&gt;
			// Set camera parameters&lt;br /&gt;
&lt;br /&gt;
			if (eye == 1)&lt;br /&gt;
 // left eye&lt;br /&gt;
				Horde3D::setNodeTransform( _cam, _x-xEyeOffset, _y, _z-zEyeOffset, _rx ,_ry-strabismus, 0, 1, 1, 1 );&lt;br /&gt;
&lt;br /&gt;
			else if (eye == 2)&lt;br /&gt;
 // right eye&lt;br /&gt;
				Horde3D::setNodeTransform( _cam, _x+xEyeOffset, _y, _z+zEyeOffset, _rx ,_ry+strabismus, 0, 1, 1, 1 );&lt;br /&gt;
&lt;br /&gt;
			else if(eye == 0)&lt;br /&gt;
 // normal camera (centered)&lt;br /&gt;
				Horde3D::setNodeTransform( _cam, _x, _y, _z, _rx ,_ry, 0, 1, 1, 1 );&lt;br /&gt;
&lt;br /&gt;
			Horde3D::render( _cam );&lt;br /&gt;
&lt;br /&gt;
			Horde3D::finalizeFrame();&lt;br /&gt;
 // comment this line if you are using Horde3D 1.0.0 beta 2&lt;br /&gt;
		}&lt;br /&gt;
&lt;br /&gt;
		// Remove all overlays&lt;br /&gt;
&lt;br /&gt;
		Horde3D::clearOverlays();&lt;br /&gt;
&lt;br /&gt;
	&lt;br /&gt;
&lt;br /&gt;
		// Write all mesages to log file&lt;br /&gt;
&lt;br /&gt;
		Horde3DUtils::dumpMessages();&lt;br /&gt;
&lt;br /&gt;
		SDL_GL_SwapBuffers();&lt;br /&gt;
&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void Application::keyPressEvent( SDLKey key )&lt;br /&gt;
&lt;br /&gt;
{&lt;br /&gt;
&lt;br /&gt;
	// add more key events here...&lt;br /&gt;
&lt;br /&gt;
	// switch between eyes (0: normal/center, 1: left eye, 2: right eye)&lt;br /&gt;
&lt;br /&gt;
	if( key == SDLK_F5 )	{// F5&lt;br /&gt;
&lt;br /&gt;
		++eye;&lt;br /&gt;
&lt;br /&gt;
		if (eye &amp;gt;= 3)&lt;br /&gt;
&lt;br /&gt;
			eye = 0;&lt;br /&gt;
&lt;br /&gt;
		std::cout&amp;lt;&amp;lt;&amp;quot;eye: &amp;quot;&amp;lt;&amp;lt;eye&amp;lt;&amp;lt;std::endl;&lt;br /&gt;
&lt;br /&gt;
	}&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void Application::keyHandler()&lt;br /&gt;
&lt;br /&gt;
{&lt;br /&gt;
	// add more keys if desired...&lt;br /&gt;
&lt;br /&gt;
	// adjust strabismus (cross eyedness)&lt;br /&gt;
	if(_keys[SDLK_0])&lt;br /&gt;
&lt;br /&gt;
	{&lt;br /&gt;
&lt;br /&gt;
		if (strabismus &amp;lt; 45)&lt;br /&gt;
&lt;br /&gt;
			strabismus += 0.3f;&lt;br /&gt;
&lt;br /&gt;
		std::cout&amp;lt;&amp;lt;&amp;quot;strabismus: &amp;quot;&amp;lt;&amp;lt;strabismus&amp;lt;&amp;lt;std::endl;&lt;br /&gt;
&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	if(_keys[SDLK_9])&lt;br /&gt;
&lt;br /&gt;
	{&lt;br /&gt;
&lt;br /&gt;
		if (strabismus &amp;gt; 0)&lt;br /&gt;
&lt;br /&gt;
			strabismus -= 0.3f;&lt;br /&gt;
&lt;br /&gt;
		std::cout&amp;lt;&amp;lt;&amp;quot;strabismus: &amp;quot;&amp;lt;&amp;lt;strabismus&amp;lt;&amp;lt;std::endl;&lt;br /&gt;
&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
	// adjust eye offset&lt;br /&gt;
	if(_keys[SDLK_8])&lt;br /&gt;
&lt;br /&gt;
	{&lt;br /&gt;
&lt;br /&gt;
		eyeOffset += 0.3f;&lt;br /&gt;
&lt;br /&gt;
		std::cout&amp;lt;&amp;lt;&amp;quot;eyeOffset: &amp;quot;&amp;lt;&amp;lt;eyeOffset&amp;lt;&amp;lt;std::endl;&lt;br /&gt;
&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	if(_keys[SDLK_7])&lt;br /&gt;
&lt;br /&gt;
	{&lt;br /&gt;
&lt;br /&gt;
		if (eyeOffset &amp;gt; 0) {&lt;br /&gt;
&lt;br /&gt;
			eyeOffset -= 0.3f;&lt;br /&gt;
&lt;br /&gt;
			std::cout&amp;lt;&amp;lt;&amp;quot;eyeOffset: &amp;quot;&amp;lt;&amp;lt;eyeOffset&amp;lt;&amp;lt;std::endl;&lt;br /&gt;
&lt;br /&gt;
		}&lt;br /&gt;
&lt;br /&gt;
	}&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
}}&lt;/div&gt;</summary>
		<author><name>Wakko</name></author>	</entry>

	<entry>
		<id>http://horde3d.org/wiki/index.php?title=Tutorial_-_Stereo_rendering&amp;diff=513</id>
		<title>Tutorial - Stereo rendering</title>
		<link rel="alternate" type="text/html" href="http://horde3d.org/wiki/index.php?title=Tutorial_-_Stereo_rendering&amp;diff=513"/>
				<updated>2009-07-11T11:11:30Z</updated>
		
		<summary type="html">&lt;p&gt;Wakko: New page: '''In this tutorial I will describe how to perform quadbuffered stereo rendering with Horde3D. This explicitly requires a graphics card that supports quad-buffering, i.e. rendering to two ...&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;'''In this tutorial I will describe how to perform quadbuffered stereo rendering with Horde3D. This explicitly requires a graphics card that supports quad-buffering, i.e. rendering to two different output devices(Nvidia Quadro or ATI/AMD FireGL). This has been tested with a stereo projection system and polarization glasses.'''&lt;br /&gt;
&lt;br /&gt;
To do this we need to render our scene from two different points of view(left and right eye) and send each frame to the corresponding output device.&lt;br /&gt;
&lt;br /&gt;
[http://www.gali-3d.com/archive/articles/StereoOpenGL/StereoscopicOpenGLTutorial.php Stereoscopic OpenGL Tutorial]&lt;br /&gt;
&lt;br /&gt;
[http://www.orthostereo.com/geometryopengl.html Stereoscopic Geometry in OpenGL]&lt;br /&gt;
In this tutorial we will only use an asymmetric frustum.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Enable quadbuffering ==&lt;br /&gt;
First of all we need to tell our graphics card to enable quadbuffering if available. The following code shows how to do this using SDL. We will try to enable stereo rendering by default but it will fall back to non-stereo if the graphics card does not have quadbuffering capabilities. We will only enable stereo rendering in fullscreen mode. &lt;br /&gt;
{{CppSourceCode|&lt;br /&gt;
description= Stereo Setup .|&lt;br /&gt;
code=&lt;br /&gt;
&amp;lt;source lang=&amp;quot;cpp&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
bool setupWindow( int width, int height, bool fullscreen )&lt;br /&gt;
{&lt;br /&gt;
	const SDL_VideoInfo* videoInfo = SDL_GetVideoInfo();&lt;br /&gt;
	SDL_Surface* surface;&lt;br /&gt;
&lt;br /&gt;
	appWidth = fullscreen ? videoInfo-&amp;gt;current_w : width;&lt;br /&gt;
	appHeight = fullscreen ? videoInfo-&amp;gt;current_h : height;&lt;br /&gt;
&lt;br /&gt;
	const bool fullscreen = true;&lt;br /&gt;
&lt;br /&gt;
	if(fullscreen)&lt;br /&gt;
	{&lt;br /&gt;
		// enable stereo if possible (only in fullscreen mode)&lt;br /&gt;
		if ( SDL_GL_SetAttribute(SDL_GL_STEREO, 1) == 0) {&lt;br /&gt;
			std::cout&amp;lt;&amp;lt;&amp;quot;Stereo flag set!&amp;quot;&amp;lt;&amp;lt;std::endl;&lt;br /&gt;
		}&lt;br /&gt;
		// Try to initialize the SDL_Surface with Stereo enabled&lt;br /&gt;
		if (!(surface =  SDL_SetVideoMode(appWidth,appHeight,32,SDL_OPENGL | SDL_FULLSCREEN | SDL_HWSURFACE))) &lt;br /&gt;
		{&lt;br /&gt;
			// if initialization with stereo enabled failed disable the stereo flag and retry&lt;br /&gt;
			std::cerr &amp;lt;&amp;lt; &amp;quot;STEREO initialization failed! Restarting...&amp;quot;&amp;lt;&amp;lt; std::endl;&lt;br /&gt;
			SDL_GL_SetAttribute(SDL_GL_STEREO, 0);&lt;br /&gt;
			if (!SDL_SetVideoMode(width, height, 32, SDL_OPENGL | SDL_FULLSCREEN | SDL_HWSURFACE)) {&lt;br /&gt;
			     std::cerr &amp;lt;&amp;lt; &amp;quot;SDL_SetVideoMode failed: &amp;quot; &amp;lt;&amp;lt; SDL_GetError() &amp;lt;&amp;lt; std::endl;&lt;br /&gt;
			     SDL_Quit();&lt;br /&gt;
			     return 0;&lt;br /&gt;
			}&lt;br /&gt;
		}&lt;br /&gt;
	}else // windowed&lt;br /&gt;
	{	&lt;br /&gt;
		if (!(surface = SDL_SetVideoMode(appWidth,appHeight,32,SDL_OPENGL | SDL_HWSURFACE))) &lt;br /&gt;
		{&lt;br /&gt;
			std::cerr &amp;lt;&amp;lt; &amp;quot;SDL_SetVideoMode failed: &amp;quot; &amp;lt;&amp;lt; SDL_GetError() &amp;lt;&amp;lt; std::endl;&lt;br /&gt;
			SDL_Quit();&lt;br /&gt;
			return 0;&lt;br /&gt;
		}&lt;br /&gt;
		SDL_WM_SetCaption(&amp;quot;SDL App&amp;quot;,NULL);&lt;br /&gt;
	}&lt;br /&gt;
	// check if stereo rendering is enabled&lt;br /&gt;
	int ga = 0;&lt;br /&gt;
	if (SDL_GL_GetAttribute(SDL_GL_STEREO, &amp;amp;ga) == 0) {&lt;br /&gt;
		if (ga == 0)&lt;br /&gt;
			std::cout&amp;lt;&amp;lt;&amp;quot;No stereo rendering available.&amp;quot;&amp;lt;&amp;lt;std::endl;&lt;br /&gt;
		else&lt;br /&gt;
			std::cout&amp;lt;&amp;lt;&amp;quot;Stereo rendering enabled!.&amp;quot;&amp;lt;&amp;lt;std::endl;&lt;br /&gt;
	}&lt;br /&gt;
	return true;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
'''work in progress'''&lt;/div&gt;</summary>
		<author><name>Wakko</name></author>	</entry>

	<entry>
		<id>http://horde3d.org/wiki/index.php?title=Horde3D_Wiki:Community_portal&amp;diff=512</id>
		<title>Horde3D Wiki:Community portal</title>
		<link rel="alternate" type="text/html" href="http://horde3d.org/wiki/index.php?title=Horde3D_Wiki:Community_portal&amp;diff=512"/>
				<updated>2009-07-11T10:35:22Z</updated>
		
		<summary type="html">&lt;p&gt;Wakko: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;__NOEDITSECTION__{{ContentBlock|color=orange&lt;br /&gt;
|content= '''The community portal section of the Horde3D wiki contains community contributed articles that are not part of the official documentation. Feel free to add articles to our wiki or links to external tutorials.'''}}&lt;br /&gt;
{{SpacerBlock}}&lt;br /&gt;
{{ContentBlock|&lt;br /&gt;
|header=Horde3D is a cross-platform graphics engine. The currently supported platform are Windows, Linux and Mac OS X.&lt;br /&gt;
|content={{!!}}&lt;br /&gt;
==Setting up the Development Environment==&lt;br /&gt;
*[[Horde3D Development Environment for Windows]]&lt;br /&gt;
*[[Horde3D Development Environment for Linux]]&lt;br /&gt;
*[[Horde3D Development Environment for Mac OS X]]&lt;br /&gt;
&lt;br /&gt;
*[[Horde3D Development Environment from SVN]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Tutorials==&lt;br /&gt;
[[Category: Tutorials]]&lt;br /&gt;
&lt;br /&gt;
===Beginner===&lt;br /&gt;
#[[Tutorial - Hello World]] - In this section we will create a simple application that loads a character and animates it using a walk cycle.&lt;br /&gt;
#[[Tutorial - Picking]] - In this section we will demonstrate picking the node under the mouse cursor&lt;br /&gt;
#[[Tutorial - Simple HUD]] - How to use showOverlay to create a simple HUD.&lt;br /&gt;
#[[Tutorial - Setup Horde with SDL]]   - How to Setup Horde with SDL.&lt;br /&gt;
#[[Tutorial - Setup Horde with Qt4]]   - How to Setup Horde with Qt4.&lt;br /&gt;
#[[Tutorial - Setup Horde with Gtkmm]] - How to Setup Horde with Gtkmm&lt;br /&gt;
#[[Tutorial - Stereo rendering]] - Basic outline for quad-buffered stereo rendering&lt;br /&gt;
&lt;br /&gt;
===Intermediate===&lt;br /&gt;
#[[Basic Pipeline Tutorial]] - Create your first custom pipeline.&lt;br /&gt;
&lt;br /&gt;
===Advanced===&lt;br /&gt;
''to come in the future''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Techniques==&lt;br /&gt;
[[Category: Techniques]]&lt;br /&gt;
&lt;br /&gt;
===Shading===&lt;br /&gt;
#[[Shading Technique - Dot Product Detail Texturing]] - Using the dot product of vectors and signed textures for high frequency detail&lt;br /&gt;
#[[Shading Technique - Palette Coloring]] - Quick and dirty palette recoloration of objects&lt;br /&gt;
#[[Shading Technique - Gloss Mapping]] - Mask which areas of an object have specular highlights&lt;br /&gt;
#[[Shading Technique - Glow Mapping]] - Allow areas on an object to emit a strong glowing highlight&lt;br /&gt;
#[[Shading Technique - Fresnel]] - Using reflection and refraction&lt;br /&gt;
#[[Shading Technique - Linear Depth Buffer]] - Create a custom linear depth buffer using vertex&lt;br /&gt;
#[[Shading Technique - Terrain Shading]] - Height and slope based shading with triplanar texturing&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===Preprocessing===&lt;br /&gt;
#[[Preprocessing Technique - Distance Field Vector Textures]] - Using Adobe Photoshop to generate textures suitable for efficient vector art rendering&lt;br /&gt;
&lt;br /&gt;
==Content/Asset Import==&lt;br /&gt;
&lt;br /&gt;
[[Category: Content Import]]&lt;br /&gt;
#[[Collada - 3DS Max and Maya]] - Exporting from 3D Studio Max and Maya.&lt;br /&gt;
#[[Collada - XSI]] - Exporting from XSI.&lt;br /&gt;
#[[Collada - Modo]] - Exporting from Modo.&lt;br /&gt;
#[[Direct Export from Blender]] - Exporting from Blender.&lt;br /&gt;
#[[AC3D]] - Converting AC3D files to Horde3D&lt;br /&gt;
#[[AssetTroubleshooting|Troubleshooting]] - ''&amp;quot;Help, my model is not showing up!&amp;quot;''&lt;br /&gt;
#[[Tips and Techniques]] - Asset creation suggestions &amp;amp; ideas for Horde3d, exporting and program quirks..&lt;br /&gt;
}}&lt;/div&gt;</summary>
		<author><name>Wakko</name></author>	</entry>

	</feed>