<?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=Darkangel</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=Darkangel"/>
		<link rel="alternate" type="text/html" href="http://horde3d.org/wiki/index.php?title=Special:Contributions/Darkangel"/>
		<updated>2026-05-05T08:39:10Z</updated>
		<subtitle>User contributions</subtitle>
		<generator>MediaWiki 1.29.3</generator>

	<entry>
		<id>http://horde3d.org/wiki/index.php?title=Code_Snippets&amp;diff=677</id>
		<title>Code Snippets</title>
		<link rel="alternate" type="text/html" href="http://horde3d.org/wiki/index.php?title=Code_Snippets&amp;diff=677"/>
				<updated>2010-08-10T15:05:42Z</updated>
		
		<summary type="html">&lt;p&gt;Darkangel: /* More procedurally generated content code */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=What is this page?=&lt;br /&gt;
This page of the wiki is a sharing zone for rough Horde example code.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== More procedurally generated content code ===&lt;br /&gt;
The following is similar but different to the [[Procedurally generated geometry tutorial]]&lt;br /&gt;
{{CppSourceCode|&lt;br /&gt;
description=Building a 2D grid of quads| &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;
void ScreenGridMesh( char*&amp;amp; data, int&amp;amp; fileSize, int&amp;amp; batchStart, int&amp;amp; batchCount, int&amp;amp; vertRStart, int&amp;amp; vertREnd )&lt;br /&gt;
{&lt;br /&gt;
	extern int appWidth;&lt;br /&gt;
	extern int appHeight;&lt;br /&gt;
&lt;br /&gt;
	//This example splits the screen up into groups of 16 pixels, and create a quad for each group.&lt;br /&gt;
	int quadSize = 16;&lt;br /&gt;
	int quadsH = (appWidth +quadSize-1) / quadSize;//divide by 16, rounding up&lt;br /&gt;
	int quadsV = (appHeight+quadSize-1) / quadSize;&lt;br /&gt;
	int quads = quadsH*quadsV;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
	int version = 5;//This is the current version of the GEO format (at the time of writing).&lt;br /&gt;
&lt;br /&gt;
	int numJoints = 0;//I don't have code below for writing joints...&lt;br /&gt;
	int numMorphTargets = 0;//...or morph targets&lt;br /&gt;
&lt;br /&gt;
//The lines that begin with //! or /*! could be used if you want a more complete vertex format (i.e. normal/binormal/tangent/joints/etc)&lt;br /&gt;
//!	int numVertexStreams = 8;&lt;br /&gt;
	int numVertexStreams = 2;//I'm just using position + tex-coord&lt;br /&gt;
&lt;br /&gt;
	int numVertices = quads * 4;// I'm making 4 verts per quad&lt;br /&gt;
	int numTriangleIndices = quads * 6;//Each quad is 2 triangles. Each triangle is made up of 3 verts, so I need 6 indices to describe each quad.&lt;br /&gt;
&lt;br /&gt;
	//These are all &amp;quot;magic numbers&amp;quot; that horde uses to interpret the data streams&lt;br /&gt;
	int vertPositionID = 0;&lt;br /&gt;
	int vertNormalID = 1;&lt;br /&gt;
	int vertTangentID = 2;&lt;br /&gt;
	int vertBiTangentID = 3;&lt;br /&gt;
	int vertJointIndexID = 4;&lt;br /&gt;
	int vertJointWeightID = 5;&lt;br /&gt;
	int vertTexCoordID = 6;&lt;br /&gt;
	int vertTexCoord2ID = 7;&lt;br /&gt;
	int positionElementSize = sizeof(float)*3;&lt;br /&gt;
	int normalElementSize   = sizeof(short)*3;&lt;br /&gt;
	int tangentElementSize  = sizeof(short)*3;&lt;br /&gt;
	int biTangentElementSize= sizeof(short)*3;&lt;br /&gt;
	int jointIndexElementSize = sizeof(char)*4;&lt;br /&gt;
	int jointWeightElementSize = sizeof(char)*4;&lt;br /&gt;
	int texCoordElementSize = sizeof(float)*2;&lt;br /&gt;
	int texCoord2ElementSize = sizeof(float)*2;&lt;br /&gt;
&lt;br /&gt;
	batchStart = 0;&lt;br /&gt;
	batchCount = numTriangleIndices;&lt;br /&gt;
	vertRStart = 0;&lt;br /&gt;
	vertREnd = numVertices-1;&lt;br /&gt;
	&lt;br /&gt;
//!	int vertDataSize = positionElementSize+normalElementSize+&lt;br /&gt;
//!	                   tangentElementSize+biTangentElementSize+&lt;br /&gt;
//!	                   jointIndexElementSize+jointWeightElementSize+&lt;br /&gt;
//!	                   texCoordElementSize+texCoord2ElementSize;&lt;br /&gt;
	int vertDataSize = positionElementSize+texCoordElementSize;&lt;br /&gt;
&lt;br /&gt;
	int quadDataSize = vertDataSize*4 + sizeof(int)*6;&lt;br /&gt;
//!	fileSize = sizeof(char)*4 + sizeof(int)*22 + quadDataSize*quads;&lt;br /&gt;
	fileSize = sizeof(char)*4 + sizeof(int)*10 + quadDataSize*quads;&lt;br /&gt;
&lt;br /&gt;
	data = new char[fileSize];&lt;br /&gt;
	int written = 0;&lt;br /&gt;
	&lt;br /&gt;
#define ASSERT( c )	\&lt;br /&gt;
	if( !(c) ) { printf( &amp;quot;ASSERTION FAILED: %s\n&amp;quot;, #c ); breakPlz(); }&lt;br /&gt;
#define WRITE_DATA( d, size )	\&lt;br /&gt;
	memcpy( &amp;amp;data[written], d, size ); written += size; ASSERT( written &amp;lt;= fileSize );&lt;br /&gt;
&lt;br /&gt;
	//First write the header&lt;br /&gt;
	WRITE_DATA( &amp;quot;H3DG&amp;quot;, sizeof(char)*4 );&lt;br /&gt;
	WRITE_DATA( &amp;amp;version, sizeof(int) );&lt;br /&gt;
&lt;br /&gt;
	//Joint data would go here, if I had any&lt;br /&gt;
	WRITE_DATA( &amp;amp;numJoints, sizeof(int) );&lt;br /&gt;
&lt;br /&gt;
	//Then write the vertex-stream header&lt;br /&gt;
	WRITE_DATA( &amp;amp;numVertexStreams, sizeof(int) );&lt;br /&gt;
	WRITE_DATA( &amp;amp;numVertices, sizeof(int) );&lt;br /&gt;
&lt;br /&gt;
	//I'm making quads in this example, so all my loops are going to create 4 pieces of each data.&lt;br /&gt;
&lt;br /&gt;
	//To begin with I write the positions:&lt;br /&gt;
	WRITE_DATA( &amp;amp;vertPositionID, sizeof(int) );&lt;br /&gt;
	WRITE_DATA( &amp;amp;positionElementSize, sizeof(int) );&lt;br /&gt;
	for( int y=0; y&amp;lt;quadsV; ++y )&lt;br /&gt;
	{&lt;br /&gt;
		for( int x=0; x&amp;lt;quadsH; ++x )&lt;br /&gt;
		{&lt;br /&gt;
			float positionA[3] = { ((x+0.0f)/(float)quadsH)*2.0f-1.0f, ((y+0.0f)/(float)quadsV)*2.0f-1.0f, 0.0f };&lt;br /&gt;
			float positionB[3] = { ((x+1.0f)/(float)quadsH)*2.0f-1.0f, ((y+0.0f)/(float)quadsV)*2.0f-1.0f, 0.0f };&lt;br /&gt;
			float positionC[3] = { ((x+1.0f)/(float)quadsH)*2.0f-1.0f, ((y+1.0f)/(float)quadsV)*2.0f-1.0f, 0.0f };&lt;br /&gt;
			float positionD[3] = { ((x+0.0f)/(float)quadsH)*2.0f-1.0f, ((y+1.0f)/(float)quadsV)*2.0f-1.0f, 0.0f };&lt;br /&gt;
			WRITE_DATA( positionA, sizeof(float)*3 );&lt;br /&gt;
			WRITE_DATA( positionB, sizeof(float)*3 );&lt;br /&gt;
			WRITE_DATA( positionC, sizeof(float)*3 );&lt;br /&gt;
			WRITE_DATA( positionD, sizeof(float)*3 );&lt;br /&gt;
		}&lt;br /&gt;
	}&lt;br /&gt;
	/*!&lt;br /&gt;
	//Normals/binormals/tangents should be floats in the 0-1 range, and then multiplied by 32767 and cast to 'short'. This is a form of compression.&lt;br /&gt;
	WRITE_DATA( &amp;amp;vertNormalID, sizeof(int) );&lt;br /&gt;
	WRITE_DATA( &amp;amp;normalElementSize, sizeof(int) );&lt;br /&gt;
	for( int i=0; i!=quads; ++i )&lt;br /&gt;
	{&lt;br /&gt;
		short n[] = { 0, 0, 32767 };&lt;br /&gt;
		WRITE_DATA( n, sizeof(short)*3 );&lt;br /&gt;
		WRITE_DATA( n, sizeof(short)*3 );&lt;br /&gt;
		WRITE_DATA( n, sizeof(short)*3 );&lt;br /&gt;
		WRITE_DATA( n, sizeof(short)*3 );&lt;br /&gt;
	}&lt;br /&gt;
	WRITE_DATA( &amp;amp;vertTangentID, sizeof(int) );&lt;br /&gt;
	WRITE_DATA( &amp;amp;tangentElementSize, sizeof(int) );&lt;br /&gt;
	for( int i=0; i!=quads; ++i )&lt;br /&gt;
	{&lt;br /&gt;
		short n[] = { 0, 32767, 0 };&lt;br /&gt;
		WRITE_DATA( n, sizeof(short)*3 );&lt;br /&gt;
		WRITE_DATA( n, sizeof(short)*3 );&lt;br /&gt;
		WRITE_DATA( n, sizeof(short)*3 );&lt;br /&gt;
		WRITE_DATA( n, sizeof(short)*3 );&lt;br /&gt;
	}&lt;br /&gt;
	WRITE_DATA( &amp;amp;vertBiTangentID, sizeof(int) );&lt;br /&gt;
	WRITE_DATA( &amp;amp;biTangentElementSize, sizeof(int) );&lt;br /&gt;
	for( int i=0; i!=quads; ++i )&lt;br /&gt;
	{&lt;br /&gt;
		short n[] = { 32767, 0, 0 };&lt;br /&gt;
		WRITE_DATA( n, sizeof(short)*3 );&lt;br /&gt;
		WRITE_DATA( n, sizeof(short)*3 );&lt;br /&gt;
		WRITE_DATA( n, sizeof(short)*3 );&lt;br /&gt;
		WRITE_DATA( n, sizeof(short)*3 );&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	//Each vertex can be influenced by 4 joints - the joint IDs are written here&lt;br /&gt;
	WRITE_DATA( &amp;amp;vertJointIndexID, sizeof(int) );&lt;br /&gt;
	WRITE_DATA( &amp;amp;jointIndexElementSize, sizeof(int) );&lt;br /&gt;
	for( int i=0; i!=quads; ++i )&lt;br /&gt;
	{&lt;br /&gt;
		char j[] = { 0, 0, 0, 0 };&lt;br /&gt;
		WRITE_DATA( j, sizeof(char)*4 );&lt;br /&gt;
		WRITE_DATA( j, sizeof(char)*4 );&lt;br /&gt;
		WRITE_DATA( j, sizeof(char)*4 );&lt;br /&gt;
		WRITE_DATA( j, sizeof(char)*4 );&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	//The 'percent' (out of 255, not out of 100) that each of the above joints influences the vertex:&lt;br /&gt;
	WRITE_DATA( &amp;amp;vertJointWeightID, sizeof(int) );&lt;br /&gt;
	WRITE_DATA( &amp;amp;jointWeightElementSize, sizeof(int) );&lt;br /&gt;
	for( int i=0; i!=quads; ++i )&lt;br /&gt;
	{&lt;br /&gt;
		ASSERT( sizeof(char) == 1 )&lt;br /&gt;
		char j[] = { 255, 0, 0, 0 };&lt;br /&gt;
		WRITE_DATA( j, sizeof(char)*4 );&lt;br /&gt;
		WRITE_DATA( j, sizeof(char)*4 );&lt;br /&gt;
		WRITE_DATA( j, sizeof(char)*4 );&lt;br /&gt;
		WRITE_DATA( j, sizeof(char)*4 );&lt;br /&gt;
	}&lt;br /&gt;
	*/&lt;br /&gt;
	//Tex-coords are pairs of floats&lt;br /&gt;
	WRITE_DATA( &amp;amp;vertTexCoordID, sizeof(int) );&lt;br /&gt;
	WRITE_DATA( &amp;amp;texCoordElementSize, sizeof(int) );&lt;br /&gt;
	for( int i=0; i!=quads; ++i )&lt;br /&gt;
	{&lt;br /&gt;
		float uvTl[] = { 0.0f, 1.0f };&lt;br /&gt;
		float uvBl[] = { 0.0f, 0.0f };&lt;br /&gt;
		float uvBr[] = { 1.0f, 0.0f };&lt;br /&gt;
		float uvTr[] = { 1.0f, 1.0f };&lt;br /&gt;
		WRITE_DATA( uvTl, sizeof(float)*2 );&lt;br /&gt;
		WRITE_DATA( uvBl, sizeof(float)*2 );&lt;br /&gt;
		WRITE_DATA( uvBr, sizeof(float)*2 );&lt;br /&gt;
		WRITE_DATA( uvTr, sizeof(float)*2 );&lt;br /&gt;
	}&lt;br /&gt;
	/*!&lt;br /&gt;
	//You can have a second set of tex-coords if you want&lt;br /&gt;
	WRITE_DATA( &amp;amp;vertTexCoord2ID, sizeof(int) );&lt;br /&gt;
	WRITE_DATA( &amp;amp;texCoord2ElementSize, sizeof(int) );&lt;br /&gt;
	for( int i=0; i!=quads; ++i )&lt;br /&gt;
	{&lt;br /&gt;
		float uvTl[] = { 0.0f, 1.0f };&lt;br /&gt;
		float uvBl[] = { 0.0f, 0.0f };&lt;br /&gt;
		float uvBr[] = { 1.0f, 0.0f };&lt;br /&gt;
		float uvTr[] = { 1.0f, 1.0f };&lt;br /&gt;
		WRITE_DATA( uvTl, sizeof(float)*2 );&lt;br /&gt;
		WRITE_DATA( uvBl, sizeof(float)*2 );&lt;br /&gt;
		WRITE_DATA( uvBr, sizeof(float)*2 );&lt;br /&gt;
		WRITE_DATA( uvTr, sizeof(float)*2 );&lt;br /&gt;
	}*/&lt;br /&gt;
&lt;br /&gt;
	//Finally, time for the index buffer&lt;br /&gt;
	WRITE_DATA( &amp;amp;numTriangleIndices, sizeof(int) );&lt;br /&gt;
	for( int i=0; i!=quads; ++i )&lt;br /&gt;
	{&lt;br /&gt;
		int base = i * 4;&lt;br /&gt;
		int a = base, b = base+1, c = base+2, d=base+2, e=base+3, f=base;&lt;br /&gt;
		WRITE_DATA( &amp;amp;a, sizeof(int) );&lt;br /&gt;
		WRITE_DATA( &amp;amp;b, sizeof(int) );&lt;br /&gt;
		WRITE_DATA( &amp;amp;c, sizeof(int) );&lt;br /&gt;
		WRITE_DATA( &amp;amp;d, sizeof(int) );&lt;br /&gt;
		WRITE_DATA( &amp;amp;e, sizeof(int) );&lt;br /&gt;
		WRITE_DATA( &amp;amp;f, sizeof(int) );&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	//Morph targets would go here, if I had any&lt;br /&gt;
	WRITE_DATA( &amp;amp;numMorphTargets, sizeof(int) );&lt;br /&gt;
&lt;br /&gt;
	ASSERT( written == fileSize );//ensure we didn't over/under-use the buffer&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
{{CppSourceCode|&lt;br /&gt;
description= Example Usage| &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;
	// Build a geo&lt;br /&gt;
	H3DRes gridGeo = h3dAddResource( H3DResTypes::Geometry, &amp;quot;runtime/blahBlah.geo&amp;quot;, H3DResFlags::NoQuery );&lt;br /&gt;
	int batchStart = 0, batchCount = 0, vertRStart = 0, vertREnd = 0;&lt;br /&gt;
	{&lt;br /&gt;
		int dataSize = 0;&lt;br /&gt;
		char* data = 0;&lt;br /&gt;
		ScreenGridMesh( data, dataSize, batchStart, batchCount, vertRStart, vertREnd );&lt;br /&gt;
		bool loadedData = h3dLoadResource( gridGeo, data, dataSize );&lt;br /&gt;
		delete [] lensBlurData;&lt;br /&gt;
	}&lt;br /&gt;
	&lt;br /&gt;
	// Load a material&lt;br /&gt;
	H3DRes material = h3dAddResource( H3DResTypes::Material, &amp;quot;materials/grid.material.xml&amp;quot;, 0 );&lt;br /&gt;
	h3dutLoadResourcesFromDisk( _contentDir.c_str() );&lt;br /&gt;
&lt;br /&gt;
	// Create a model/mesh from the procedural geo&lt;br /&gt;
	H3DNode model = h3dAddModelNode( H3DRootNode, &amp;quot;MyModel&amp;quot;, gridGeo );&lt;br /&gt;
	H3DNode mesh = h3dAddMeshNode( model, &amp;quot;MyMesh&amp;quot;, material, batchStart, batchCount, vertRStart, vertREnd );&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
}}&lt;/div&gt;</summary>
		<author><name>Darkangel</name></author>	</entry>

	<entry>
		<id>http://horde3d.org/wiki/index.php?title=Code_Snippets&amp;diff=676</id>
		<title>Code Snippets</title>
		<link rel="alternate" type="text/html" href="http://horde3d.org/wiki/index.php?title=Code_Snippets&amp;diff=676"/>
				<updated>2010-08-10T15:02:41Z</updated>
		
		<summary type="html">&lt;p&gt;Darkangel: /* More procedurally generated content code */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=What is this page?=&lt;br /&gt;
This page of the wiki is a sharing zone for rough Horde example code.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== More procedurally generated content code ===&lt;br /&gt;
The following is similar but different to the [[Procedurally generated geometry tutorial]]&lt;br /&gt;
{{CppSourceCode|&lt;br /&gt;
description=Building a 2D grid of points| &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;
void ScreenGridMesh( char*&amp;amp; data, int&amp;amp; fileSize, int&amp;amp; batchStart, int&amp;amp; batchCount, int&amp;amp; vertRStart, int&amp;amp; vertREnd )&lt;br /&gt;
{&lt;br /&gt;
	extern int appWidth;&lt;br /&gt;
	extern int appHeight;&lt;br /&gt;
&lt;br /&gt;
	//This example splits the screen up into groups of 16 pixels, and create a quad for each group.&lt;br /&gt;
	int quadSize = 16;&lt;br /&gt;
	int quadsH = (appWidth +quadSize-1) / quadSize;//divide by 16, rounding up&lt;br /&gt;
	int quadsV = (appHeight+quadSize-1) / quadSize;&lt;br /&gt;
	int quads = quadsH*quadsV;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
	int version = 5;//This is the current version of the GEO format (at the time of writing).&lt;br /&gt;
&lt;br /&gt;
	int numJoints = 0;//I don't have code below for writing joints...&lt;br /&gt;
	int numMorphTargets = 0;//...or morph targets&lt;br /&gt;
&lt;br /&gt;
//The lines that begin with //! or /*! could be used if you want a more complete vertex format (i.e. normal/binormal/tangent/joints/etc)&lt;br /&gt;
//!	int numVertexStreams = 8;&lt;br /&gt;
	int numVertexStreams = 2;//I'm just using position + tex-coord&lt;br /&gt;
&lt;br /&gt;
	int numVertices = quads * 4;// I'm making 4 verts per quad&lt;br /&gt;
	int numTriangleIndices = quads * 6;//Each quad is 2 triangles. Each triangle is made up of 3 verts, so I need 6 indices to describe each quad.&lt;br /&gt;
&lt;br /&gt;
	//These are all &amp;quot;magic numbers&amp;quot; that horde uses to interpret the data streams&lt;br /&gt;
	int vertPositionID = 0;&lt;br /&gt;
	int vertNormalID = 1;&lt;br /&gt;
	int vertTangentID = 2;&lt;br /&gt;
	int vertBiTangentID = 3;&lt;br /&gt;
	int vertJointIndexID = 4;&lt;br /&gt;
	int vertJointWeightID = 5;&lt;br /&gt;
	int vertTexCoordID = 6;&lt;br /&gt;
	int vertTexCoord2ID = 7;&lt;br /&gt;
	int positionElementSize = sizeof(float)*3;&lt;br /&gt;
	int normalElementSize   = sizeof(short)*3;&lt;br /&gt;
	int tangentElementSize  = sizeof(short)*3;&lt;br /&gt;
	int biTangentElementSize= sizeof(short)*3;&lt;br /&gt;
	int jointIndexElementSize = sizeof(char)*4;&lt;br /&gt;
	int jointWeightElementSize = sizeof(char)*4;&lt;br /&gt;
	int texCoordElementSize = sizeof(float)*2;&lt;br /&gt;
	int texCoord2ElementSize = sizeof(float)*2;&lt;br /&gt;
&lt;br /&gt;
	batchStart = 0;&lt;br /&gt;
	batchCount = numTriangleIndices;&lt;br /&gt;
	vertRStart = 0;&lt;br /&gt;
	vertREnd = numVertices-1;&lt;br /&gt;
	&lt;br /&gt;
//!	int vertDataSize = positionElementSize+normalElementSize+&lt;br /&gt;
//!	                   tangentElementSize+biTangentElementSize+&lt;br /&gt;
//!	                   jointIndexElementSize+jointWeightElementSize+&lt;br /&gt;
//!	                   texCoordElementSize+texCoord2ElementSize;&lt;br /&gt;
	int vertDataSize = positionElementSize+texCoordElementSize;&lt;br /&gt;
&lt;br /&gt;
	int quadDataSize = vertDataSize*4 + sizeof(int)*6;&lt;br /&gt;
//!	fileSize = sizeof(char)*4 + sizeof(int)*22 + quadDataSize*quads;&lt;br /&gt;
	fileSize = sizeof(char)*4 + sizeof(int)*10 + quadDataSize*quads;&lt;br /&gt;
&lt;br /&gt;
	data = new char[fileSize];&lt;br /&gt;
	int written = 0;&lt;br /&gt;
	&lt;br /&gt;
#define ASSERT( c )	\&lt;br /&gt;
	if( !(c) ) { printf( &amp;quot;ASSERTION FAILED: %s\n&amp;quot;, #c ); breakPlz(); }&lt;br /&gt;
#define WRITE_DATA( d, size )	\&lt;br /&gt;
	memcpy( &amp;amp;data[written], d, size ); written += size; ASSERT( written &amp;lt;= fileSize );&lt;br /&gt;
&lt;br /&gt;
	//First write the header&lt;br /&gt;
	WRITE_DATA( &amp;quot;H3DG&amp;quot;, sizeof(char)*4 );&lt;br /&gt;
	WRITE_DATA( &amp;amp;version, sizeof(int) );&lt;br /&gt;
&lt;br /&gt;
	//Joint data would go here, if I had any&lt;br /&gt;
	WRITE_DATA( &amp;amp;numJoints, sizeof(int) );&lt;br /&gt;
&lt;br /&gt;
	//Then write the vertex-stream header&lt;br /&gt;
	WRITE_DATA( &amp;amp;numVertexStreams, sizeof(int) );&lt;br /&gt;
	WRITE_DATA( &amp;amp;numVertices, sizeof(int) );&lt;br /&gt;
&lt;br /&gt;
	//I'm making quads in this example, so all my loops are going to create 4 pieces of each data.&lt;br /&gt;
&lt;br /&gt;
	//To begin with I write the positions:&lt;br /&gt;
	WRITE_DATA( &amp;amp;vertPositionID, sizeof(int) );&lt;br /&gt;
	WRITE_DATA( &amp;amp;positionElementSize, sizeof(int) );&lt;br /&gt;
	for( int y=0; y&amp;lt;quadsV; ++y )&lt;br /&gt;
	{&lt;br /&gt;
		for( int x=0; x&amp;lt;quadsH; ++x )&lt;br /&gt;
		{&lt;br /&gt;
			float positionA[3] = { ((x+0.0f)/(float)quadsH)*2.0f-1.0f, ((y+0.0f)/(float)quadsV)*2.0f-1.0f, 0.0f };&lt;br /&gt;
			float positionB[3] = { ((x+1.0f)/(float)quadsH)*2.0f-1.0f, ((y+0.0f)/(float)quadsV)*2.0f-1.0f, 0.0f };&lt;br /&gt;
			float positionC[3] = { ((x+1.0f)/(float)quadsH)*2.0f-1.0f, ((y+1.0f)/(float)quadsV)*2.0f-1.0f, 0.0f };&lt;br /&gt;
			float positionD[3] = { ((x+0.0f)/(float)quadsH)*2.0f-1.0f, ((y+1.0f)/(float)quadsV)*2.0f-1.0f, 0.0f };&lt;br /&gt;
			WRITE_DATA( positionA, sizeof(float)*3 );&lt;br /&gt;
			WRITE_DATA( positionB, sizeof(float)*3 );&lt;br /&gt;
			WRITE_DATA( positionC, sizeof(float)*3 );&lt;br /&gt;
			WRITE_DATA( positionD, sizeof(float)*3 );&lt;br /&gt;
		}&lt;br /&gt;
	}&lt;br /&gt;
	/*!&lt;br /&gt;
	//Normals/binormals/tangents should be floats in the 0-1 range, and then multiplied by 32767 and cast to 'short'. This is a form of compression.&lt;br /&gt;
	WRITE_DATA( &amp;amp;vertNormalID, sizeof(int) );&lt;br /&gt;
	WRITE_DATA( &amp;amp;normalElementSize, sizeof(int) );&lt;br /&gt;
	for( int i=0; i!=quads; ++i )&lt;br /&gt;
	{&lt;br /&gt;
		short n[] = { 0, 0, 32767 };&lt;br /&gt;
		WRITE_DATA( n, sizeof(short)*3 );&lt;br /&gt;
		WRITE_DATA( n, sizeof(short)*3 );&lt;br /&gt;
		WRITE_DATA( n, sizeof(short)*3 );&lt;br /&gt;
		WRITE_DATA( n, sizeof(short)*3 );&lt;br /&gt;
	}&lt;br /&gt;
	WRITE_DATA( &amp;amp;vertTangentID, sizeof(int) );&lt;br /&gt;
	WRITE_DATA( &amp;amp;tangentElementSize, sizeof(int) );&lt;br /&gt;
	for( int i=0; i!=quads; ++i )&lt;br /&gt;
	{&lt;br /&gt;
		short n[] = { 0, 32767, 0 };&lt;br /&gt;
		WRITE_DATA( n, sizeof(short)*3 );&lt;br /&gt;
		WRITE_DATA( n, sizeof(short)*3 );&lt;br /&gt;
		WRITE_DATA( n, sizeof(short)*3 );&lt;br /&gt;
		WRITE_DATA( n, sizeof(short)*3 );&lt;br /&gt;
	}&lt;br /&gt;
	WRITE_DATA( &amp;amp;vertBiTangentID, sizeof(int) );&lt;br /&gt;
	WRITE_DATA( &amp;amp;biTangentElementSize, sizeof(int) );&lt;br /&gt;
	for( int i=0; i!=quads; ++i )&lt;br /&gt;
	{&lt;br /&gt;
		short n[] = { 32767, 0, 0 };&lt;br /&gt;
		WRITE_DATA( n, sizeof(short)*3 );&lt;br /&gt;
		WRITE_DATA( n, sizeof(short)*3 );&lt;br /&gt;
		WRITE_DATA( n, sizeof(short)*3 );&lt;br /&gt;
		WRITE_DATA( n, sizeof(short)*3 );&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	//Each vertex can be influenced by 4 joints - the joint IDs are written here&lt;br /&gt;
	WRITE_DATA( &amp;amp;vertJointIndexID, sizeof(int) );&lt;br /&gt;
	WRITE_DATA( &amp;amp;jointIndexElementSize, sizeof(int) );&lt;br /&gt;
	for( int i=0; i!=quads; ++i )&lt;br /&gt;
	{&lt;br /&gt;
		char j[] = { 0, 0, 0, 0 };&lt;br /&gt;
		WRITE_DATA( j, sizeof(char)*4 );&lt;br /&gt;
		WRITE_DATA( j, sizeof(char)*4 );&lt;br /&gt;
		WRITE_DATA( j, sizeof(char)*4 );&lt;br /&gt;
		WRITE_DATA( j, sizeof(char)*4 );&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	//The 'percent' (out of 255, not out of 100) that each of the above joints influences the vertex:&lt;br /&gt;
	WRITE_DATA( &amp;amp;vertJointWeightID, sizeof(int) );&lt;br /&gt;
	WRITE_DATA( &amp;amp;jointWeightElementSize, sizeof(int) );&lt;br /&gt;
	for( int i=0; i!=quads; ++i )&lt;br /&gt;
	{&lt;br /&gt;
		ASSERT( sizeof(char) == 1 )&lt;br /&gt;
		char j[] = { 255, 0, 0, 0 };&lt;br /&gt;
		WRITE_DATA( j, sizeof(char)*4 );&lt;br /&gt;
		WRITE_DATA( j, sizeof(char)*4 );&lt;br /&gt;
		WRITE_DATA( j, sizeof(char)*4 );&lt;br /&gt;
		WRITE_DATA( j, sizeof(char)*4 );&lt;br /&gt;
	}&lt;br /&gt;
	*/&lt;br /&gt;
	//Tex-coords are pairs of floats&lt;br /&gt;
	WRITE_DATA( &amp;amp;vertTexCoordID, sizeof(int) );&lt;br /&gt;
	WRITE_DATA( &amp;amp;texCoordElementSize, sizeof(int) );&lt;br /&gt;
	for( int i=0; i!=quads; ++i )&lt;br /&gt;
	{&lt;br /&gt;
		float uvTl[] = { 0.0f, 1.0f };&lt;br /&gt;
		float uvBl[] = { 0.0f, 0.0f };&lt;br /&gt;
		float uvBr[] = { 1.0f, 0.0f };&lt;br /&gt;
		float uvTr[] = { 1.0f, 1.0f };&lt;br /&gt;
		WRITE_DATA( uvTl, sizeof(float)*2 );&lt;br /&gt;
		WRITE_DATA( uvBl, sizeof(float)*2 );&lt;br /&gt;
		WRITE_DATA( uvBr, sizeof(float)*2 );&lt;br /&gt;
		WRITE_DATA( uvTr, sizeof(float)*2 );&lt;br /&gt;
	}&lt;br /&gt;
	/*!&lt;br /&gt;
	//You can have a second set of tex-coords if you want&lt;br /&gt;
	WRITE_DATA( &amp;amp;vertTexCoord2ID, sizeof(int) );&lt;br /&gt;
	WRITE_DATA( &amp;amp;texCoord2ElementSize, sizeof(int) );&lt;br /&gt;
	for( int i=0; i!=quads; ++i )&lt;br /&gt;
	{&lt;br /&gt;
		float uvTl[] = { 0.0f, 1.0f };&lt;br /&gt;
		float uvBl[] = { 0.0f, 0.0f };&lt;br /&gt;
		float uvBr[] = { 1.0f, 0.0f };&lt;br /&gt;
		float uvTr[] = { 1.0f, 1.0f };&lt;br /&gt;
		WRITE_DATA( uvTl, sizeof(float)*2 );&lt;br /&gt;
		WRITE_DATA( uvBl, sizeof(float)*2 );&lt;br /&gt;
		WRITE_DATA( uvBr, sizeof(float)*2 );&lt;br /&gt;
		WRITE_DATA( uvTr, sizeof(float)*2 );&lt;br /&gt;
	}*/&lt;br /&gt;
&lt;br /&gt;
	//Finally, time for the index buffer&lt;br /&gt;
	WRITE_DATA( &amp;amp;numTriangleIndices, sizeof(int) );&lt;br /&gt;
	for( int i=0; i!=quads; ++i )&lt;br /&gt;
	{&lt;br /&gt;
		int base = i * 4;&lt;br /&gt;
		int a = base, b = base+1, c = base+2, d=base+2, e=base+3, f=base;&lt;br /&gt;
		WRITE_DATA( &amp;amp;a, sizeof(int) );&lt;br /&gt;
		WRITE_DATA( &amp;amp;b, sizeof(int) );&lt;br /&gt;
		WRITE_DATA( &amp;amp;c, sizeof(int) );&lt;br /&gt;
		WRITE_DATA( &amp;amp;d, sizeof(int) );&lt;br /&gt;
		WRITE_DATA( &amp;amp;e, sizeof(int) );&lt;br /&gt;
		WRITE_DATA( &amp;amp;f, sizeof(int) );&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	//Morph targets would go here, if I had any&lt;br /&gt;
	WRITE_DATA( &amp;amp;numMorphTargets, sizeof(int) );&lt;br /&gt;
&lt;br /&gt;
	ASSERT( written == fileSize );//ensure we didn't over/under-use the buffer&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
{{CppSourceCode|&lt;br /&gt;
description= Example Usage| &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;
	// Build a geo&lt;br /&gt;
	H3DRes gridGeo = h3dAddResource( H3DResTypes::Geometry, &amp;quot;runtime/blahBlah.geo&amp;quot;, H3DResFlags::NoQuery );&lt;br /&gt;
	int batchStart = 0, batchCount = 0, vertRStart = 0, vertREnd = 0;&lt;br /&gt;
	{&lt;br /&gt;
		int dataSize = 0;&lt;br /&gt;
		char* data = 0;&lt;br /&gt;
		BuildLensBlurMesh( data, dataSize, batchStart, batchCount, vertRStart, vertREnd );&lt;br /&gt;
		bool loadedData = h3dLoadResource( gridGeo, data, dataSize );&lt;br /&gt;
		delete [] lensBlurData;&lt;br /&gt;
	}&lt;br /&gt;
	&lt;br /&gt;
	// Load a material&lt;br /&gt;
	H3DRes material = h3dAddResource( H3DResTypes::Material, &amp;quot;materials/grid.material.xml&amp;quot;, 0 );&lt;br /&gt;
	h3dutLoadResourcesFromDisk( _contentDir.c_str() );&lt;br /&gt;
&lt;br /&gt;
	// Create a model/mesh from the procedural geo&lt;br /&gt;
	H3DNode model = h3dAddModelNode( H3DRootNode, &amp;quot;MyModel&amp;quot;, gridGeo );&lt;br /&gt;
	H3DNode mesh = h3dAddMeshNode( model, &amp;quot;MyMesh&amp;quot;, material, batchStart, batchCount, vertRStart, vertREnd );&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
}}&lt;/div&gt;</summary>
		<author><name>Darkangel</name></author>	</entry>

	<entry>
		<id>http://horde3d.org/wiki/index.php?title=Code_Snippets&amp;diff=675</id>
		<title>Code Snippets</title>
		<link rel="alternate" type="text/html" href="http://horde3d.org/wiki/index.php?title=Code_Snippets&amp;diff=675"/>
				<updated>2010-08-10T15:00:08Z</updated>
		
		<summary type="html">&lt;p&gt;Darkangel: /* More procedurally generated content code */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=What is this page?=&lt;br /&gt;
This page of the wiki is a sharing zone for rough Horde example code.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== More procedurally generated content code ===&lt;br /&gt;
The following is similar but different to the [[Procedurally generated geometry tutorial]]&lt;br /&gt;
{{CppSourceCode|&lt;br /&gt;
description=Building a 2D grid of points| &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;
void ScreenGridMesh( char*&amp;amp; data, int&amp;amp; fileSize, int&amp;amp; batchStart, int&amp;amp; batchCount, int&amp;amp; vertRStart, int&amp;amp; vertREnd )&lt;br /&gt;
{&lt;br /&gt;
	extern int appWidth;&lt;br /&gt;
	extern int appHeight;&lt;br /&gt;
&lt;br /&gt;
	//This example splits the screen up into groups of 16 pixels, and create a quad for each group.&lt;br /&gt;
	int quadSize = 16;&lt;br /&gt;
	int quadSizeHalf = quadSize/2;&lt;br /&gt;
	int quadsH = (appWidth +quadSize-1) / quadSize;//divide by 16, rounding up&lt;br /&gt;
	int quadsV = (appHeight+quadSize-1) / quadSize;&lt;br /&gt;
	int quads = quadsH*quadsV;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
	int version = 5;&lt;br /&gt;
	int numJoints = 0;//I don't have code below for writing joints...&lt;br /&gt;
	int numMorphTargets = 0;//...or morph targets&lt;br /&gt;
&lt;br /&gt;
//The lines that begin with //! or /*! could be used if you want a more complete vertex format (i.e. normal/binormal/tangent/joints/etc)&lt;br /&gt;
//!	int numVertexStreams = 8;&lt;br /&gt;
	int numVertexStreams = 2;//I'm just using position + tex-coord&lt;br /&gt;
&lt;br /&gt;
	int numVertices = quads * 4;// I'm making 4 verts per quad&lt;br /&gt;
	int numTriangleIndices = quads * 6;//Each quad is 2 triangles. Each triangle is made up of 3 verts, so I need 6 indices to describe each quad.&lt;br /&gt;
&lt;br /&gt;
	int vertPositionID = 0;&lt;br /&gt;
	int vertNormalID = 1;&lt;br /&gt;
	int vertTangentID = 2;&lt;br /&gt;
	int vertBiTangentID = 3;&lt;br /&gt;
	int vertJointIndexID = 4;&lt;br /&gt;
	int vertJointWeightID = 5;&lt;br /&gt;
	int vertTexCoordID = 6;&lt;br /&gt;
	int vertTexCoord2ID = 7;&lt;br /&gt;
	int positionElementSize = sizeof(float)*3;&lt;br /&gt;
	int normalElementSize   = sizeof(short)*3;&lt;br /&gt;
	int tangentElementSize  = sizeof(short)*3;&lt;br /&gt;
	int biTangentElementSize= sizeof(short)*3;&lt;br /&gt;
	int jointIndexElementSize = sizeof(char)*4;&lt;br /&gt;
	int jointWeightElementSize = sizeof(char)*4;&lt;br /&gt;
	int texCoordElementSize = sizeof(float)*2;&lt;br /&gt;
	int texCoord2ElementSize = sizeof(float)*2;&lt;br /&gt;
&lt;br /&gt;
	batchStart = 0;&lt;br /&gt;
	batchCount = numTriangleIndices;&lt;br /&gt;
	vertRStart = 0;&lt;br /&gt;
	vertREnd = numVertices-1;&lt;br /&gt;
	&lt;br /&gt;
//!	int vertDataSize = positionElementSize+normalElementSize+&lt;br /&gt;
	                   tangentElementSize+biTangentElementSize+&lt;br /&gt;
	                   jointIndexElementSize+jointWeightElementSize+&lt;br /&gt;
	                   texCoordElementSize+texCoord2ElementSize;&lt;br /&gt;
	int vertDataSize = positionElementSize+texCoordElementSize;&lt;br /&gt;
&lt;br /&gt;
	int quadDataSize = vertDataSize*4 + sizeof(int)*6;&lt;br /&gt;
//!	fileSize = sizeof(char)*4 + sizeof(int)*22 + quadDataSize*quads;&lt;br /&gt;
	fileSize = sizeof(char)*4 + sizeof(int)*10 + quadDataSize*quads;&lt;br /&gt;
&lt;br /&gt;
	data = new char[fileSize];&lt;br /&gt;
	int written = 0;&lt;br /&gt;
	&lt;br /&gt;
#define ASSERT( c )	\&lt;br /&gt;
	if( !(c) ) { printf( &amp;quot;ASSERTION FAILED: %s\n&amp;quot;, #c ); breakPlz(); }&lt;br /&gt;
#define WRITE_DATA( d, size )	\&lt;br /&gt;
	memcpy( &amp;amp;data[written], d, size ); written += size; ASSERT( written &amp;lt;= fileSize );&lt;br /&gt;
&lt;br /&gt;
	//First write the header&lt;br /&gt;
	WRITE_DATA( &amp;quot;H3DG&amp;quot;, sizeof(char)*4 );&lt;br /&gt;
	WRITE_DATA( &amp;amp;version, sizeof(int) );&lt;br /&gt;
&lt;br /&gt;
	//Joint data would go here, if I had any&lt;br /&gt;
	WRITE_DATA( &amp;amp;numJoints, sizeof(int) );&lt;br /&gt;
&lt;br /&gt;
	//Then write the vertex-stream header&lt;br /&gt;
	WRITE_DATA( &amp;amp;numVertexStreams, sizeof(int) );&lt;br /&gt;
	WRITE_DATA( &amp;amp;numVertices, sizeof(int) );&lt;br /&gt;
&lt;br /&gt;
	//I'm making quads in this example, so all my loops are going to create 4 pieces of each data.&lt;br /&gt;
&lt;br /&gt;
	//To begin with I write the positions:&lt;br /&gt;
	WRITE_DATA( &amp;amp;vertPositionID, sizeof(int) );&lt;br /&gt;
	WRITE_DATA( &amp;amp;positionElementSize, sizeof(int) );&lt;br /&gt;
	for( int y=0; y&amp;lt;quadsV; ++y )&lt;br /&gt;
	{&lt;br /&gt;
		for( int x=0; x&amp;lt;quadsH; ++x )&lt;br /&gt;
		{&lt;br /&gt;
			float positionA[3] = { ((x+0.0f)/(float)quadsH)*2.0f-1.0f, ((y+0.0f)/(float)quadsV)*2.0f-1.0f, 0.0f };&lt;br /&gt;
			float positionB[3] = { ((x+1.0f)/(float)quadsH)*2.0f-1.0f, ((y+0.0f)/(float)quadsV)*2.0f-1.0f, 0.0f };&lt;br /&gt;
			float positionC[3] = { ((x+1.0f)/(float)quadsH)*2.0f-1.0f, ((y+1.0f)/(float)quadsV)*2.0f-1.0f, 0.0f };&lt;br /&gt;
			float positionD[3] = { ((x+0.0f)/(float)quadsH)*2.0f-1.0f, ((y+1.0f)/(float)quadsV)*2.0f-1.0f, 0.0f };&lt;br /&gt;
			WRITE_DATA( positionA, sizeof(float)*3 );&lt;br /&gt;
			WRITE_DATA( positionB, sizeof(float)*3 );&lt;br /&gt;
			WRITE_DATA( positionC, sizeof(float)*3 );&lt;br /&gt;
			WRITE_DATA( positionD, sizeof(float)*3 );&lt;br /&gt;
		}&lt;br /&gt;
	}&lt;br /&gt;
	/*!&lt;br /&gt;
	//Normals/binormals/tangents should be floats in the 0-1 range, and then multiplied by 32767 and cast to 'short'. This is a form of compression.&lt;br /&gt;
	WRITE_DATA( &amp;amp;vertNormalID, sizeof(int) );&lt;br /&gt;
	WRITE_DATA( &amp;amp;normalElementSize, sizeof(int) );&lt;br /&gt;
	for( int i=0; i!=quads; ++i )&lt;br /&gt;
	{&lt;br /&gt;
		short n[] = { 0, 0, 32767 };&lt;br /&gt;
		WRITE_DATA( n, sizeof(short)*3 );&lt;br /&gt;
		WRITE_DATA( n, sizeof(short)*3 );&lt;br /&gt;
		WRITE_DATA( n, sizeof(short)*3 );&lt;br /&gt;
		WRITE_DATA( n, sizeof(short)*3 );&lt;br /&gt;
	}&lt;br /&gt;
	WRITE_DATA( &amp;amp;vertTangentID, sizeof(int) );&lt;br /&gt;
	WRITE_DATA( &amp;amp;tangentElementSize, sizeof(int) );&lt;br /&gt;
	for( int i=0; i!=quads; ++i )&lt;br /&gt;
	{&lt;br /&gt;
		short n[] = { 0, 32767, 0 };&lt;br /&gt;
		WRITE_DATA( n, sizeof(short)*3 );&lt;br /&gt;
		WRITE_DATA( n, sizeof(short)*3 );&lt;br /&gt;
		WRITE_DATA( n, sizeof(short)*3 );&lt;br /&gt;
		WRITE_DATA( n, sizeof(short)*3 );&lt;br /&gt;
	}&lt;br /&gt;
	WRITE_DATA( &amp;amp;vertBiTangentID, sizeof(int) );&lt;br /&gt;
	WRITE_DATA( &amp;amp;biTangentElementSize, sizeof(int) );&lt;br /&gt;
	for( int i=0; i!=quads; ++i )&lt;br /&gt;
	{&lt;br /&gt;
		short n[] = { 32767, 0, 0 };&lt;br /&gt;
		WRITE_DATA( n, sizeof(short)*3 );&lt;br /&gt;
		WRITE_DATA( n, sizeof(short)*3 );&lt;br /&gt;
		WRITE_DATA( n, sizeof(short)*3 );&lt;br /&gt;
		WRITE_DATA( n, sizeof(short)*3 );&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	//Each vertex can be influenced by 4 joints - the joint IDs are written here&lt;br /&gt;
	WRITE_DATA( &amp;amp;vertJointIndexID, sizeof(int) );&lt;br /&gt;
	WRITE_DATA( &amp;amp;jointIndexElementSize, sizeof(int) );&lt;br /&gt;
	for( int i=0; i!=quads; ++i )&lt;br /&gt;
	{&lt;br /&gt;
		char j[] = { 0, 0, 0, 0 };&lt;br /&gt;
		WRITE_DATA( j, sizeof(char)*4 );&lt;br /&gt;
		WRITE_DATA( j, sizeof(char)*4 );&lt;br /&gt;
		WRITE_DATA( j, sizeof(char)*4 );&lt;br /&gt;
		WRITE_DATA( j, sizeof(char)*4 );&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	//The 'percent' (out of 255, not out of 100) that each of the above joints influences the vertex:&lt;br /&gt;
	WRITE_DATA( &amp;amp;vertJointWeightID, sizeof(int) );&lt;br /&gt;
	WRITE_DATA( &amp;amp;jointWeightElementSize, sizeof(int) );&lt;br /&gt;
	for( int i=0; i!=quads; ++i )&lt;br /&gt;
	{&lt;br /&gt;
		ASSERT( sizeof(char) == 1 )&lt;br /&gt;
		char j[] = { 255, 0, 0, 0 };&lt;br /&gt;
		WRITE_DATA( j, sizeof(char)*4 );&lt;br /&gt;
		WRITE_DATA( j, sizeof(char)*4 );&lt;br /&gt;
		WRITE_DATA( j, sizeof(char)*4 );&lt;br /&gt;
		WRITE_DATA( j, sizeof(char)*4 );&lt;br /&gt;
	}&lt;br /&gt;
	*/&lt;br /&gt;
	//Tex-coords are pairs of floats&lt;br /&gt;
	WRITE_DATA( &amp;amp;vertTexCoordID, sizeof(int) );&lt;br /&gt;
	WRITE_DATA( &amp;amp;texCoordElementSize, sizeof(int) );&lt;br /&gt;
	for( int i=0; i!=quads; ++i )&lt;br /&gt;
	{&lt;br /&gt;
		float uvTl[] = { 0.0f, 1.0f };&lt;br /&gt;
		float uvBl[] = { 0.0f, 0.0f };&lt;br /&gt;
		float uvBr[] = { 1.0f, 0.0f };&lt;br /&gt;
		float uvTr[] = { 1.0f, 1.0f };&lt;br /&gt;
		WRITE_DATA( uvTl, sizeof(float)*2 );&lt;br /&gt;
		WRITE_DATA( uvBl, sizeof(float)*2 );&lt;br /&gt;
		WRITE_DATA( uvBr, sizeof(float)*2 );&lt;br /&gt;
		WRITE_DATA( uvTr, sizeof(float)*2 );&lt;br /&gt;
	}&lt;br /&gt;
	/*!&lt;br /&gt;
	//You can have a second set of tex-coords if you want&lt;br /&gt;
	WRITE_DATA( &amp;amp;vertTexCoord2ID, sizeof(int) );&lt;br /&gt;
	WRITE_DATA( &amp;amp;texCoord2ElementSize, sizeof(int) );&lt;br /&gt;
	for( int i=0; i!=quads; ++i )&lt;br /&gt;
	{&lt;br /&gt;
		float uvTl[] = { 0.0f, 1.0f };&lt;br /&gt;
		float uvBl[] = { 0.0f, 0.0f };&lt;br /&gt;
		float uvBr[] = { 1.0f, 0.0f };&lt;br /&gt;
		float uvTr[] = { 1.0f, 1.0f };&lt;br /&gt;
		WRITE_DATA( uvTl, sizeof(float)*2 );&lt;br /&gt;
		WRITE_DATA( uvBl, sizeof(float)*2 );&lt;br /&gt;
		WRITE_DATA( uvBr, sizeof(float)*2 );&lt;br /&gt;
		WRITE_DATA( uvTr, sizeof(float)*2 );&lt;br /&gt;
	}*/&lt;br /&gt;
&lt;br /&gt;
	//Finally, time for the index buffer&lt;br /&gt;
	WRITE_DATA( &amp;amp;numTriangleIndices, sizeof(int) );&lt;br /&gt;
	for( int i=0; i!=quads; ++i )&lt;br /&gt;
	{&lt;br /&gt;
		int base = i * 4;&lt;br /&gt;
		int a = base, b = base+1, c = base+2, d=base+2, e=base+3, f=base;&lt;br /&gt;
		WRITE_DATA( &amp;amp;a, sizeof(int) );&lt;br /&gt;
		WRITE_DATA( &amp;amp;b, sizeof(int) );&lt;br /&gt;
		WRITE_DATA( &amp;amp;c, sizeof(int) );&lt;br /&gt;
		WRITE_DATA( &amp;amp;d, sizeof(int) );&lt;br /&gt;
		WRITE_DATA( &amp;amp;e, sizeof(int) );&lt;br /&gt;
		WRITE_DATA( &amp;amp;f, sizeof(int) );&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	//Morph targets would go here, if I had any&lt;br /&gt;
	WRITE_DATA( &amp;amp;numMorphTargets, sizeof(int) );&lt;br /&gt;
&lt;br /&gt;
	ASSERT( written == fileSize );//ensure we didn't over/under-use the buffer&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
{{CppSourceCode|&lt;br /&gt;
description= Example Usage| &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;
	// Build a geo&lt;br /&gt;
	H3DRes gridGeo = h3dAddResource( H3DResTypes::Geometry, &amp;quot;runtime/blahBlah.geo&amp;quot;, H3DResFlags::NoQuery );&lt;br /&gt;
	int batchStart = 0, batchCount = 0, vertRStart = 0, vertREnd = 0;&lt;br /&gt;
	{&lt;br /&gt;
		int dataSize = 0;&lt;br /&gt;
		char* data = 0;&lt;br /&gt;
		BuildLensBlurMesh( data, dataSize, batchStart, batchCount, vertRStart, vertREnd );&lt;br /&gt;
		bool loadedData = h3dLoadResource( gridGeo, data, dataSize );&lt;br /&gt;
		delete [] lensBlurData;&lt;br /&gt;
	}&lt;br /&gt;
	&lt;br /&gt;
	// Load a material&lt;br /&gt;
	H3DRes material = h3dAddResource( H3DResTypes::Material, &amp;quot;materials/grid.material.xml&amp;quot;, 0 );&lt;br /&gt;
	h3dutLoadResourcesFromDisk( _contentDir.c_str() );&lt;br /&gt;
&lt;br /&gt;
	// Create a model/mesh from the procedural geo&lt;br /&gt;
	H3DNode model = h3dAddModelNode( H3DRootNode, &amp;quot;MyModel&amp;quot;, gridGeo );&lt;br /&gt;
	H3DNode mesh = h3dAddMeshNode( model, &amp;quot;MyMesh&amp;quot;, material, batchStart, batchCount, vertRStart, vertREnd );&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
}}&lt;/div&gt;</summary>
		<author><name>Darkangel</name></author>	</entry>

	<entry>
		<id>http://horde3d.org/wiki/index.php?title=Code_Snippets&amp;diff=674</id>
		<title>Code Snippets</title>
		<link rel="alternate" type="text/html" href="http://horde3d.org/wiki/index.php?title=Code_Snippets&amp;diff=674"/>
				<updated>2010-08-10T14:53:14Z</updated>
		
		<summary type="html">&lt;p&gt;Darkangel: Snippets!&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=What is this page?=&lt;br /&gt;
This page of the wiki is a sharing zone for rough Horde example code.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== More procedurally generated content code ===&lt;br /&gt;
The following is similar but different to the [[Procedurally generated geometry tutorial]]&lt;br /&gt;
{{CppSourceCode|&lt;br /&gt;
description=Building a 2D grid of points| &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;
void ScreenGridMesh( char*&amp;amp; data, int&amp;amp; fileSize, int&amp;amp; batchStart, int&amp;amp; batchCount, int&amp;amp; vertRStart, int&amp;amp; vertREnd )&lt;br /&gt;
{&lt;br /&gt;
	extern int appWidth;&lt;br /&gt;
	extern int appHeight;&lt;br /&gt;
&lt;br /&gt;
	//This example splits the screen up into groups of 16 pixels, and create a quad for each group.&lt;br /&gt;
	int quadSize = 16;&lt;br /&gt;
	int quadSizeHalf = quadSize/2;&lt;br /&gt;
	int quadsH = (appWidth +quadSize-1) / quadSize;//divide by 16, rounding up&lt;br /&gt;
	int quadsV = (appHeight+quadSize-1) / quadSize;&lt;br /&gt;
	int quads = quadsH*quadsV;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
	int version = 5;&lt;br /&gt;
	int numJoints = 0;//I don't have code below for writing joints&lt;br /&gt;
&lt;br /&gt;
//The lines that begin with //! or /*! could be used if you want a more complete vertex format (i.e. normal/binormal/tangent/joints/etc)&lt;br /&gt;
//!	int numVertexStreams = 8;&lt;br /&gt;
	int numVertexStreams = 2;&lt;br /&gt;
	int numVertices = quads * 4;&lt;br /&gt;
	int vertPositionID = 0;&lt;br /&gt;
	int vertNormalID = 1;&lt;br /&gt;
	int vertTangentID = 2;&lt;br /&gt;
	int vertBiTangentID = 3;&lt;br /&gt;
	int vertJointIndexID = 4;&lt;br /&gt;
	int vertJointWeightID = 5;&lt;br /&gt;
	int vertTexCoordID = 6;&lt;br /&gt;
	int vertTexCoord2ID = 7;&lt;br /&gt;
	int positionElementSize = sizeof(float)*3;&lt;br /&gt;
	int normalElementSize   = sizeof(short)*3;&lt;br /&gt;
	int tangentElementSize  = sizeof(short)*3;&lt;br /&gt;
	int biTangentElementSize= sizeof(short)*3;&lt;br /&gt;
	int jointIndexElementSize = sizeof(char)*4;&lt;br /&gt;
	int jointWeightElementSize = sizeof(char)*4;&lt;br /&gt;
	int texCoordElementSize = sizeof(float)*2;&lt;br /&gt;
	int texCoord2ElementSize = sizeof(float)*2;&lt;br /&gt;
	int numTriangleIndices = quads * 6;&lt;br /&gt;
	int numMorphTargets = 0;&lt;br /&gt;
&lt;br /&gt;
	batchStart = 0;&lt;br /&gt;
	batchCount = numTriangleIndices;&lt;br /&gt;
	vertRStart = 0;&lt;br /&gt;
	vertREnd = numVertices-1;&lt;br /&gt;
	&lt;br /&gt;
//!	int vertDataSize = positionElementSize+normalElementSize+tangentElementSize+biTangentElementSize+jointIndexElementSize+jointWeightElementSize+texCoordElementSize+texCoord2ElementSize;&lt;br /&gt;
	int vertDataSize = positionElementSize+texCoordElementSize;&lt;br /&gt;
&lt;br /&gt;
	int quadDataSize = vertDataSize*4 + sizeof(int)*6;&lt;br /&gt;
//!	fileSize = sizeof(char)*4 + sizeof(int)*22 + quadDataSize*quads;&lt;br /&gt;
	fileSize = sizeof(char)*4 + sizeof(int)*10 + quadDataSize*quads;&lt;br /&gt;
&lt;br /&gt;
	data = new char[fileSize];&lt;br /&gt;
	int written = 0;&lt;br /&gt;
	&lt;br /&gt;
#define ASSERT( c )	\&lt;br /&gt;
	if( !(c) ) { printf( &amp;quot;ASSERTION FAILED: %s\n&amp;quot;, #c ); breakPlz(); }&lt;br /&gt;
#define WRITE_DATA( d, size )	\&lt;br /&gt;
	memcpy( &amp;amp;data[written], d, size ); written += size; ASSERT( written &amp;lt;= fileSize );&lt;br /&gt;
&lt;br /&gt;
	WRITE_DATA( &amp;quot;H3DG&amp;quot;, sizeof(char)*4 );&lt;br /&gt;
	WRITE_DATA( &amp;amp;version, sizeof(int) );&lt;br /&gt;
	WRITE_DATA( &amp;amp;numJoints, sizeof(int) );&lt;br /&gt;
	WRITE_DATA( &amp;amp;numVertexStreams, sizeof(int) );&lt;br /&gt;
	WRITE_DATA( &amp;amp;numVertices, sizeof(int) );&lt;br /&gt;
&lt;br /&gt;
	//I'm making quads in this example, so all my loops are going to create 4 pieces of each data.&lt;br /&gt;
&lt;br /&gt;
	//To begin with I write the positions:&lt;br /&gt;
	WRITE_DATA( &amp;amp;vertPositionID, sizeof(int) );&lt;br /&gt;
	WRITE_DATA( &amp;amp;positionElementSize, sizeof(int) );&lt;br /&gt;
	for( int y=0; y&amp;lt;quadsV; ++y )&lt;br /&gt;
	{&lt;br /&gt;
		for( int x=0; x&amp;lt;quadsH; ++x )&lt;br /&gt;
		{&lt;br /&gt;
			float positionA[3] = { ((x+0.0f)/(float)quadsH)*2.0f-1.0f, ((y+0.0f)/(float)quadsV)*2.0f-1.0f, 0.0f };&lt;br /&gt;
			float positionB[3] = { ((x+1.0f)/(float)quadsH)*2.0f-1.0f, ((y+0.0f)/(float)quadsV)*2.0f-1.0f, 0.0f };&lt;br /&gt;
			float positionC[3] = { ((x+1.0f)/(float)quadsH)*2.0f-1.0f, ((y+1.0f)/(float)quadsV)*2.0f-1.0f, 0.0f };&lt;br /&gt;
			float positionD[3] = { ((x+0.0f)/(float)quadsH)*2.0f-1.0f, ((y+1.0f)/(float)quadsV)*2.0f-1.0f, 0.0f };&lt;br /&gt;
			WRITE_DATA( positionA, sizeof(float)*3 );&lt;br /&gt;
			WRITE_DATA( positionB, sizeof(float)*3 );&lt;br /&gt;
			WRITE_DATA( positionC, sizeof(float)*3 );&lt;br /&gt;
			WRITE_DATA( positionD, sizeof(float)*3 );&lt;br /&gt;
		}&lt;br /&gt;
	}&lt;br /&gt;
	/*!&lt;br /&gt;
	//Normals/binormals/tangents should be floats in the 0-1 range, and then multiplied by 32767 and cast to 'short'. This is a form of compression.&lt;br /&gt;
	WRITE_DATA( &amp;amp;vertNormalID, sizeof(int) );&lt;br /&gt;
	WRITE_DATA( &amp;amp;normalElementSize, sizeof(int) );&lt;br /&gt;
	for( int i=0; i!=quads; ++i )&lt;br /&gt;
	{&lt;br /&gt;
		short n[] = { 0, 0, 32767 };&lt;br /&gt;
		WRITE_DATA( n, sizeof(short)*3 );&lt;br /&gt;
		WRITE_DATA( n, sizeof(short)*3 );&lt;br /&gt;
		WRITE_DATA( n, sizeof(short)*3 );&lt;br /&gt;
		WRITE_DATA( n, sizeof(short)*3 );&lt;br /&gt;
	}&lt;br /&gt;
	WRITE_DATA( &amp;amp;vertTangentID, sizeof(int) );&lt;br /&gt;
	WRITE_DATA( &amp;amp;tangentElementSize, sizeof(int) );&lt;br /&gt;
	for( int i=0; i!=quads; ++i )&lt;br /&gt;
	{&lt;br /&gt;
		short n[] = { 0, 32767, 0 };&lt;br /&gt;
		WRITE_DATA( n, sizeof(short)*3 );&lt;br /&gt;
		WRITE_DATA( n, sizeof(short)*3 );&lt;br /&gt;
		WRITE_DATA( n, sizeof(short)*3 );&lt;br /&gt;
		WRITE_DATA( n, sizeof(short)*3 );&lt;br /&gt;
	}&lt;br /&gt;
	WRITE_DATA( &amp;amp;vertBiTangentID, sizeof(int) );&lt;br /&gt;
	WRITE_DATA( &amp;amp;biTangentElementSize, sizeof(int) );&lt;br /&gt;
	for( int i=0; i!=quads; ++i )&lt;br /&gt;
	{&lt;br /&gt;
		short n[] = { 32767, 0, 0 };&lt;br /&gt;
		WRITE_DATA( n, sizeof(short)*3 );&lt;br /&gt;
		WRITE_DATA( n, sizeof(short)*3 );&lt;br /&gt;
		WRITE_DATA( n, sizeof(short)*3 );&lt;br /&gt;
		WRITE_DATA( n, sizeof(short)*3 );&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	//Each vertex can be influenced by 4 joints - the joint IDs are written here&lt;br /&gt;
	WRITE_DATA( &amp;amp;vertJointIndexID, sizeof(int) );&lt;br /&gt;
	WRITE_DATA( &amp;amp;jointIndexElementSize, sizeof(int) );&lt;br /&gt;
	for( int i=0; i!=quads; ++i )&lt;br /&gt;
	{&lt;br /&gt;
		char j[] = { 0, 0, 0, 0 };&lt;br /&gt;
		WRITE_DATA( j, sizeof(char)*4 );&lt;br /&gt;
		WRITE_DATA( j, sizeof(char)*4 );&lt;br /&gt;
		WRITE_DATA( j, sizeof(char)*4 );&lt;br /&gt;
		WRITE_DATA( j, sizeof(char)*4 );&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	//The 'percent' (out of 255, not out of 100) that each of the above joints influences the vertex:&lt;br /&gt;
	WRITE_DATA( &amp;amp;vertJointWeightID, sizeof(int) );&lt;br /&gt;
	WRITE_DATA( &amp;amp;jointWeightElementSize, sizeof(int) );&lt;br /&gt;
	for( int i=0; i!=quads; ++i )&lt;br /&gt;
	{&lt;br /&gt;
		ASSERT( sizeof(char) == 1 )&lt;br /&gt;
		char j[] = { 255, 0, 0, 0 };&lt;br /&gt;
		WRITE_DATA( j, sizeof(char)*4 );&lt;br /&gt;
		WRITE_DATA( j, sizeof(char)*4 );&lt;br /&gt;
		WRITE_DATA( j, sizeof(char)*4 );&lt;br /&gt;
		WRITE_DATA( j, sizeof(char)*4 );&lt;br /&gt;
	}&lt;br /&gt;
	*/&lt;br /&gt;
	//Tex-coords are pairs of floats&lt;br /&gt;
	WRITE_DATA( &amp;amp;vertTexCoordID, sizeof(int) );&lt;br /&gt;
	WRITE_DATA( &amp;amp;texCoordElementSize, sizeof(int) );&lt;br /&gt;
	for( int i=0; i!=quads; ++i )&lt;br /&gt;
	{&lt;br /&gt;
		float uvTl[] = { 0.0f, 1.0f };&lt;br /&gt;
		float uvBl[] = { 0.0f, 0.0f };&lt;br /&gt;
		float uvBr[] = { 1.0f, 0.0f };&lt;br /&gt;
		float uvTr[] = { 1.0f, 1.0f };&lt;br /&gt;
		WRITE_DATA( uvTl, sizeof(float)*2 );&lt;br /&gt;
		WRITE_DATA( uvBl, sizeof(float)*2 );&lt;br /&gt;
		WRITE_DATA( uvBr, sizeof(float)*2 );&lt;br /&gt;
		WRITE_DATA( uvTr, sizeof(float)*2 );&lt;br /&gt;
	}&lt;br /&gt;
	/*!&lt;br /&gt;
	//You can have a second set of tex-coords if you want&lt;br /&gt;
	WRITE_DATA( &amp;amp;vertTexCoord2ID, sizeof(int) );&lt;br /&gt;
	WRITE_DATA( &amp;amp;texCoord2ElementSize, sizeof(int) );&lt;br /&gt;
	for( int i=0; i!=quads; ++i )&lt;br /&gt;
	{&lt;br /&gt;
		float uvTl[] = { 0.0f, 1.0f };&lt;br /&gt;
		float uvBl[] = { 0.0f, 0.0f };&lt;br /&gt;
		float uvBr[] = { 1.0f, 0.0f };&lt;br /&gt;
		float uvTr[] = { 1.0f, 1.0f };&lt;br /&gt;
		WRITE_DATA( uvTl, sizeof(float)*2 );&lt;br /&gt;
		WRITE_DATA( uvBl, sizeof(float)*2 );&lt;br /&gt;
		WRITE_DATA( uvBr, sizeof(float)*2 );&lt;br /&gt;
		WRITE_DATA( uvTr, sizeof(float)*2 );&lt;br /&gt;
	}*/&lt;br /&gt;
&lt;br /&gt;
	//Finally, time for the index buffer&lt;br /&gt;
	WRITE_DATA( &amp;amp;numTriangleIndices, sizeof(int) );&lt;br /&gt;
	for( int i=0; i!=quads; ++i )&lt;br /&gt;
	{&lt;br /&gt;
		int base = i * 4;&lt;br /&gt;
		int a = base, b = base+1, c = base+2, d=base+2, e=base+3, f=base;&lt;br /&gt;
		WRITE_DATA( &amp;amp;a, sizeof(int) );&lt;br /&gt;
		WRITE_DATA( &amp;amp;b, sizeof(int) );&lt;br /&gt;
		WRITE_DATA( &amp;amp;c, sizeof(int) );&lt;br /&gt;
		WRITE_DATA( &amp;amp;d, sizeof(int) );&lt;br /&gt;
		WRITE_DATA( &amp;amp;e, sizeof(int) );&lt;br /&gt;
		WRITE_DATA( &amp;amp;f, sizeof(int) );&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	//Morph targets would go here, if I had any&lt;br /&gt;
	WRITE_DATA( &amp;amp;numMorphTargets, sizeof(int) );&lt;br /&gt;
&lt;br /&gt;
	ASSERT( written == fileSize );//ensure we didn't over/under-use the buffer&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
{{CppSourceCode|&lt;br /&gt;
description= Example Usage| &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;
	// Build a geo&lt;br /&gt;
	H3DRes gridGeo = h3dAddResource( H3DResTypes::Geometry, &amp;quot;runtime/blahBlah.geo&amp;quot;, H3DResFlags::NoQuery );&lt;br /&gt;
	int batchStart = 0, batchCount = 0, vertRStart = 0, vertREnd = 0;&lt;br /&gt;
	{&lt;br /&gt;
		int dataSize = 0;&lt;br /&gt;
		char* data = 0;&lt;br /&gt;
		BuildLensBlurMesh( data, dataSize, batchStart, batchCount, vertRStart, vertREnd );&lt;br /&gt;
		bool loadedData = h3dLoadResource( gridGeo, data, dataSize );&lt;br /&gt;
		delete [] lensBlurData;&lt;br /&gt;
	}&lt;br /&gt;
	&lt;br /&gt;
	// Load a material&lt;br /&gt;
	H3DRes material = h3dAddResource( H3DResTypes::Material, &amp;quot;materials/grid.material.xml&amp;quot;, 0 );&lt;br /&gt;
	h3dutLoadResourcesFromDisk( _contentDir.c_str() );&lt;br /&gt;
&lt;br /&gt;
	// Create a model/mesh from the procedural geo&lt;br /&gt;
	H3DNode model = h3dAddModelNode( H3DRootNode, &amp;quot;MyModel&amp;quot;, gridGeo );&lt;br /&gt;
	H3DNode mesh = h3dAddMeshNode( model, &amp;quot;MyMesh&amp;quot;, material, batchStart, batchCount, vertRStart, vertREnd );&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
}}&lt;/div&gt;</summary>
		<author><name>Darkangel</name></author>	</entry>

	<entry>
		<id>http://horde3d.org/wiki/index.php?title=Shading_Technique_-_Glow_Mapping&amp;diff=300</id>
		<title>Shading Technique - Glow Mapping</title>
		<link rel="alternate" type="text/html" href="http://horde3d.org/wiki/index.php?title=Shading_Technique_-_Glow_Mapping&amp;diff=300"/>
				<updated>2008-08-08T00:15:11Z</updated>
		
		<summary type="html">&lt;p&gt;Darkangel: fixed a typo&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{|  border=&amp;quot;0&amp;quot; &lt;br /&gt;
| {{ContentBlock|width=800|color=white&lt;br /&gt;
|content={{!!}}&lt;br /&gt;
&lt;br /&gt;
'''I'm in the process of writing this article - come back later!'''&lt;br /&gt;
&lt;br /&gt;
== Overview ==&lt;br /&gt;
For an in-depth overview of this technique, see the Gamasutra article [http://www.gamasutra.com/features/20040526/james_pfv.htm Real-Time Glow] by By Greg James and John O’Rorke.&lt;br /&gt;
&lt;br /&gt;
== Temporary code dump == &lt;br /&gt;
Until I finish writing this article, here's the undocumented code ;)&lt;br /&gt;
&lt;br /&gt;
'''Pipeline changes'''&lt;br /&gt;
&lt;br /&gt;
{{CppSourceCode|&lt;br /&gt;
description= Setup the RenderTargets. If this is for HDR, then these RenderTargets will already exist, so just change depthBuf to &amp;quot;true&amp;quot; on the first one|&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;
&amp;lt;Setup&amp;gt;&lt;br /&gt;
	&amp;lt;RenderTarget id=&amp;quot;BLURBUF1&amp;quot; depthBuf=&amp;quot;true&amp;quot;  numColBufs=&amp;quot;1&amp;quot; format=&amp;quot;RGBA8&amp;quot; bilinear=&amp;quot;true&amp;quot; scale=&amp;quot;0.25&amp;quot; /&amp;gt;&lt;br /&gt;
	&amp;lt;RenderTarget id=&amp;quot;BLURBUF2&amp;quot; depthBuf=&amp;quot;false&amp;quot; numColBufs=&amp;quot;1&amp;quot; format=&amp;quot;RGBA8&amp;quot; bilinear=&amp;quot;true&amp;quot; scale=&amp;quot;0.25&amp;quot; /&amp;gt;&lt;br /&gt;
&amp;lt;/Setup&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;}}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{{CppSourceCode|&lt;br /&gt;
description= insert this new stage after the &amp;quot;Geometry&amp;quot; stage.|&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;
&amp;lt;stage id=&amp;quot;Glow&amp;quot;&amp;gt;&lt;br /&gt;
	&amp;lt;SwitchTarget target=&amp;quot;BLURBUF1&amp;quot; /&amp;gt;			&lt;br /&gt;
	&amp;lt;ClearTarget depthBuf=&amp;quot;true&amp;quot; colBuf0=&amp;quot;true&amp;quot; /&amp;gt;&lt;br /&gt;
	&amp;lt;DrawGeometry context=&amp;quot;GLOWMASK&amp;quot; /&amp;gt;&lt;br /&gt;
	&lt;br /&gt;
	&amp;lt;!-- Repeat these steps as many times as you like, it makes the bloom softer --&amp;gt;&lt;br /&gt;
	&amp;lt;SwitchTarget target=&amp;quot;BLURBUF2&amp;quot; /&amp;gt;&lt;br /&gt;
	&amp;lt;BindBuffer texUnit=&amp;quot;0&amp;quot; target=&amp;quot;BLURBUF1&amp;quot; bufIndex=&amp;quot;0&amp;quot; /&amp;gt;&lt;br /&gt;
	&amp;lt;DrawQuad   material=&amp;quot;postGlow.material.xml&amp;quot; context=&amp;quot;BLURV&amp;quot; /&amp;gt;&lt;br /&gt;
	&amp;lt;SwitchTarget target=&amp;quot;BLURBUF1&amp;quot; /&amp;gt;&lt;br /&gt;
	&amp;lt;BindBuffer texUnit=&amp;quot;0&amp;quot; target=&amp;quot;BLURBUF2&amp;quot; bufIndex=&amp;quot;0&amp;quot; /&amp;gt;&lt;br /&gt;
	&amp;lt;DrawQuad   material=&amp;quot;postGlow.material.xml&amp;quot; context=&amp;quot;BLURH&amp;quot; /&amp;gt;&lt;br /&gt;
	&lt;br /&gt;
	&amp;lt;SwitchTarget target=&amp;quot;BLURBUF2&amp;quot; /&amp;gt;&lt;br /&gt;
	&amp;lt;BindBuffer texUnit=&amp;quot;0&amp;quot; target=&amp;quot;BLURBUF1&amp;quot; bufIndex=&amp;quot;0&amp;quot; /&amp;gt;&lt;br /&gt;
	&amp;lt;DrawQuad   material=&amp;quot;postGlow.material.xml&amp;quot; context=&amp;quot;BLURV&amp;quot; /&amp;gt;&lt;br /&gt;
	&amp;lt;SwitchTarget target=&amp;quot;BLURBUF1&amp;quot; /&amp;gt;&lt;br /&gt;
	&amp;lt;BindBuffer texUnit=&amp;quot;0&amp;quot; target=&amp;quot;BLURBUF2&amp;quot; bufIndex=&amp;quot;0&amp;quot; /&amp;gt;&lt;br /&gt;
	&amp;lt;DrawQuad   material=&amp;quot;postGlow.material.xml&amp;quot; context=&amp;quot;BLURH&amp;quot; /&amp;gt;&lt;br /&gt;
	&lt;br /&gt;
	&amp;lt;SwitchTarget target=&amp;quot;BLURBUF2&amp;quot; /&amp;gt;&lt;br /&gt;
	&amp;lt;BindBuffer texUnit=&amp;quot;0&amp;quot; target=&amp;quot;BLURBUF1&amp;quot; bufIndex=&amp;quot;0&amp;quot; /&amp;gt;&lt;br /&gt;
	&amp;lt;DrawQuad   material=&amp;quot;postGlow.material.xml&amp;quot; context=&amp;quot;BLURV&amp;quot; /&amp;gt;&lt;br /&gt;
	&amp;lt;SwitchTarget target=&amp;quot;BLURBUF1&amp;quot; /&amp;gt;&lt;br /&gt;
	&amp;lt;BindBuffer texUnit=&amp;quot;0&amp;quot; target=&amp;quot;BLURBUF2&amp;quot; bufIndex=&amp;quot;0&amp;quot; /&amp;gt;&lt;br /&gt;
	&amp;lt;DrawQuad   material=&amp;quot;postGlow.material.xml&amp;quot; context=&amp;quot;BLURH&amp;quot; /&amp;gt;&lt;br /&gt;
	&lt;br /&gt;
	&amp;lt;!-- In the HDR version, target should be set to &amp;quot;HDRBUF&amp;quot; --&amp;gt;&lt;br /&gt;
	&amp;lt;SwitchTarget target=&amp;quot;&amp;quot; /&amp;gt;&lt;br /&gt;
	&amp;lt;BindBuffer texUnit=&amp;quot;0&amp;quot; target=&amp;quot;BLURBUF1&amp;quot; bufIndex=&amp;quot;0&amp;quot; /&amp;gt;&lt;br /&gt;
	&amp;lt;DrawQuad material=&amp;quot;postGlow.material.xml&amp;quot; context=&amp;quot;FINALPASS&amp;quot; /&amp;gt;&lt;br /&gt;
&amp;lt;/stage&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;}}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''New shader code'''&lt;br /&gt;
&lt;br /&gt;
{{CppSourceCode|&lt;br /&gt;
description= This context is designed to be added to a copy of the parallax shader - parallax_glow.shader.xml|&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;
&amp;lt;Context id=&amp;quot;GLOWMASK&amp;quot;&amp;gt;	&lt;br /&gt;
	&amp;lt;!-- This material does glow - output colors masked by the alpha channel --&amp;gt;&lt;br /&gt;
	&amp;lt;VertexShader&amp;gt;&lt;br /&gt;
		&amp;lt;InsCode code=&amp;quot;utilityLib/vertCommon.glsl&amp;quot; /&amp;gt;&lt;br /&gt;
		&amp;lt;DefCode&amp;gt;&lt;br /&gt;
		&amp;lt;![CDATA[&lt;br /&gt;
			uniform vec3 viewer;&lt;br /&gt;
			attribute vec2 texCoords0;&lt;br /&gt;
			attribute vec3 normal, tangent, bitangent;&lt;br /&gt;
			varying vec3 eyeTS;&lt;br /&gt;
			varying vec2 texCoords;&lt;br /&gt;
			varying vec4 pos;&lt;br /&gt;
		&lt;br /&gt;
			void main( void )&lt;br /&gt;
			{&lt;br /&gt;
				// Transform tangent space basis&lt;br /&gt;
				vec3 tsbTangent = normalize( calcWorldVec( tangent ) );&lt;br /&gt;
				vec3 tsbBitangent = normalize( calcWorldVec( bitangent ) );&lt;br /&gt;
				vec3 tsbNormal = normalize( calcWorldVec( normal ) );&lt;br /&gt;
				&lt;br /&gt;
				// Calculate world space position&lt;br /&gt;
				pos = calcWorldPos( gl_Vertex );&lt;br /&gt;
				&lt;br /&gt;
				// Eye vector and eye vector in tangent space&lt;br /&gt;
				eyeTS = calcTanVec( viewer - pos.xyz, tsbTangent, tsbBitangent, tsbNormal );&lt;br /&gt;
		&lt;br /&gt;
				// Calculate texture coordinates and clip space position&lt;br /&gt;
				texCoords = texCoords0;&lt;br /&gt;
				gl_Position = gl_ModelViewProjectionMatrix * pos;&lt;br /&gt;
			}&lt;br /&gt;
		]]&amp;gt;&lt;br /&gt;
		&amp;lt;/DefCode&amp;gt;&lt;br /&gt;
	&amp;lt;/VertexShader&amp;gt;&lt;br /&gt;
	&lt;br /&gt;
	&amp;lt;FragmentShader&amp;gt;&lt;br /&gt;
		&amp;lt;DefCode&amp;gt;&lt;br /&gt;
		&amp;lt;![CDATA[&lt;br /&gt;
			uniform sampler2D tex0;&lt;br /&gt;
			varying vec3 eyeTS;&lt;br /&gt;
			varying vec2 texCoords;&lt;br /&gt;
			&lt;br /&gt;
			void main( void )&lt;br /&gt;
			{&lt;br /&gt;
				const float plxScale = 0.03;&lt;br /&gt;
				const float plxBias = -0.015;&lt;br /&gt;
				&lt;br /&gt;
				// Iterative parallax mapping&lt;br /&gt;
				vec3 newCoords = vec3( texCoords, 0 );&lt;br /&gt;
				vec3 eye = normalize( eyeTS );&lt;br /&gt;
				for( int i = 0; i &amp;lt; 4; ++i )&lt;br /&gt;
				{&lt;br /&gt;
					vec4 nmap = texture2D( tex0, texCoords.st );&lt;br /&gt;
					float height = nmap.a * plxScale + plxBias;&lt;br /&gt;
					newCoords += (height - newCoords.p) * nmap.z * eye;&lt;br /&gt;
				}&lt;br /&gt;
				&lt;br /&gt;
				vec4 glow = texture2D( tex0, newCoords.st ).rgba;&lt;br /&gt;
				glow *= glow.a;&lt;br /&gt;
				&lt;br /&gt;
				gl_FragColor = glow;&lt;br /&gt;
			}&lt;br /&gt;
		]]&amp;gt;&lt;br /&gt;
		&amp;lt;/DefCode&amp;gt;&lt;br /&gt;
	&amp;lt;/FragmentShader&amp;gt;&lt;br /&gt;
&amp;lt;/Context&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;}}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{{CppSourceCode|&lt;br /&gt;
description= This is a new shader, called postGlow.shader.xml|&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;
&amp;lt;Shader&amp;gt;&lt;br /&gt;
	&lt;br /&gt;
	&amp;lt;Context id=&amp;quot;BLURH&amp;quot;&amp;gt;&lt;br /&gt;
		&amp;lt;RenderConfig writeDepth=&amp;quot;false&amp;quot; /&amp;gt;&lt;br /&gt;
		&amp;lt;VertexShader&amp;gt;&lt;br /&gt;
			&amp;lt;DefCode&amp;gt;&lt;br /&gt;
			&amp;lt;![CDATA[&lt;br /&gt;
				varying vec2 texCoord;&lt;br /&gt;
				void main( void )&lt;br /&gt;
				{&lt;br /&gt;
					texCoord = gl_MultiTexCoord0.st; &lt;br /&gt;
					gl_Position = gl_ProjectionMatrix * gl_Vertex;&lt;br /&gt;
				}&lt;br /&gt;
			]]&amp;gt;&lt;br /&gt;
			&amp;lt;/DefCode&amp;gt;&lt;br /&gt;
		&amp;lt;/VertexShader&amp;gt;&lt;br /&gt;
		&amp;lt;FragmentShader&amp;gt;&lt;br /&gt;
			&amp;lt;InsCode code=&amp;quot;utilityLib/fragPostProcess.glsl&amp;quot; /&amp;gt;&lt;br /&gt;
			&amp;lt;DefCode&amp;gt;&lt;br /&gt;
			&amp;lt;![CDATA[&lt;br /&gt;
				uniform sampler2D tex;&lt;br /&gt;
				uniform vec2 frameBufSize;&lt;br /&gt;
				varying vec2 texCoord;&lt;br /&gt;
				void main( void )&lt;br /&gt;
				{	&lt;br /&gt;
					float halfPixel = 0.5 / frameBufSize.x;&lt;br /&gt;
					vec4 col  = texture2D( tex, texCoord + vec2( halfPixel,   0.0 ) );&lt;br /&gt;
					     col += texture2D( tex, texCoord - vec2( halfPixel,   0.0 ) );&lt;br /&gt;
					     col += texture2D( tex, texCoord + vec2( halfPixel*3.0, 0.0 ) );&lt;br /&gt;
					     col += texture2D( tex, texCoord - vec2( halfPixel*3.0, 0.0 ) );&lt;br /&gt;
					gl_FragColor = col * 0.25; &lt;br /&gt;
				}&lt;br /&gt;
			]]&amp;gt;&lt;br /&gt;
			&amp;lt;/DefCode&amp;gt;&lt;br /&gt;
		&amp;lt;/FragmentShader&amp;gt;&lt;br /&gt;
	&amp;lt;/Context&amp;gt;&lt;br /&gt;
	&amp;lt;Context id=&amp;quot;BLURV&amp;quot;&amp;gt;&lt;br /&gt;
		&amp;lt;RenderConfig writeDepth=&amp;quot;false&amp;quot; /&amp;gt;&lt;br /&gt;
		&amp;lt;VertexShader&amp;gt;&lt;br /&gt;
			&amp;lt;DefCode&amp;gt;&lt;br /&gt;
			&amp;lt;![CDATA[&lt;br /&gt;
				varying vec2 texCoord;&lt;br /&gt;
				void main( void )&lt;br /&gt;
				{&lt;br /&gt;
					texCoord = gl_MultiTexCoord0.st; &lt;br /&gt;
					gl_Position = gl_ProjectionMatrix * gl_Vertex;&lt;br /&gt;
				}&lt;br /&gt;
			]]&amp;gt;&lt;br /&gt;
			&amp;lt;/DefCode&amp;gt;&lt;br /&gt;
		&amp;lt;/VertexShader&amp;gt;&lt;br /&gt;
		&amp;lt;FragmentShader&amp;gt;&lt;br /&gt;
			&amp;lt;InsCode code=&amp;quot;utilityLib/fragPostProcess.glsl&amp;quot; /&amp;gt;&lt;br /&gt;
			&amp;lt;DefCode&amp;gt;&lt;br /&gt;
			&amp;lt;![CDATA[&lt;br /&gt;
				uniform sampler2D tex;&lt;br /&gt;
				uniform vec2 frameBufSize;&lt;br /&gt;
				varying vec2 texCoord;&lt;br /&gt;
				void main( void )&lt;br /&gt;
				{	&lt;br /&gt;
					float halfPixel = 0.5 / frameBufSize.y;&lt;br /&gt;
					vec4 col  = texture2D( tex, texCoord + vec2( 0.0, halfPixel   ) );&lt;br /&gt;
					     col += texture2D( tex, texCoord - vec2( 0.0, halfPixel   ) );&lt;br /&gt;
					     col += texture2D( tex, texCoord + vec2( 0.0, halfPixel*3.0 ) );&lt;br /&gt;
					     col += texture2D( tex, texCoord - vec2( 0.0, halfPixel*3.0 ) );&lt;br /&gt;
					gl_FragColor = col * 0.25;&lt;br /&gt;
				}&lt;br /&gt;
			]]&amp;gt;&lt;br /&gt;
			&amp;lt;/DefCode&amp;gt;&lt;br /&gt;
		&amp;lt;/FragmentShader&amp;gt;&lt;br /&gt;
	&amp;lt;/Context&amp;gt;&lt;br /&gt;
	&lt;br /&gt;
	&amp;lt;Context id=&amp;quot;FINALPASS&amp;quot;&amp;gt;&lt;br /&gt;
		&amp;lt;RenderConfig writeDepth=&amp;quot;false&amp;quot; blendMode=&amp;quot;ADD&amp;quot; /&amp;gt;&lt;br /&gt;
		&lt;br /&gt;
		&amp;lt;VertexShader&amp;gt;&lt;br /&gt;
			&amp;lt;DefCode&amp;gt;&lt;br /&gt;
			&amp;lt;![CDATA[&lt;br /&gt;
				varying vec2 texCoord;&lt;br /&gt;
				&lt;br /&gt;
				void main( void )&lt;br /&gt;
				{&lt;br /&gt;
					texCoord = gl_MultiTexCoord0.st; &lt;br /&gt;
					gl_Position = gl_ProjectionMatrix * gl_Vertex;&lt;br /&gt;
				}&lt;br /&gt;
			]]&amp;gt;&lt;br /&gt;
			&amp;lt;/DefCode&amp;gt;&lt;br /&gt;
		&amp;lt;/VertexShader&amp;gt;&lt;br /&gt;
		&lt;br /&gt;
		&amp;lt;FragmentShader&amp;gt;&lt;br /&gt;
			&amp;lt;DefCode&amp;gt;&lt;br /&gt;
			&amp;lt;![CDATA[&lt;br /&gt;
				uniform sampler2D tex0, tex1;&lt;br /&gt;
				uniform vec2 frameBufSize;&lt;br /&gt;
				uniform vec4 hdrParams;&lt;br /&gt;
				varying vec2 texCoord;&lt;br /&gt;
				&lt;br /&gt;
				void main( void )&lt;br /&gt;
				{&lt;br /&gt;
					gl_FragColor = texture2D( tex0, texCoord );	// Glow color&lt;br /&gt;
				}&lt;br /&gt;
			]]&amp;gt;&lt;br /&gt;
			&amp;lt;/DefCode&amp;gt;&lt;br /&gt;
		&amp;lt;/FragmentShader&amp;gt;&lt;br /&gt;
	&amp;lt;/Context&amp;gt;&lt;br /&gt;
&amp;lt;/Shader&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;}}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{{CppSourceCode|&lt;br /&gt;
description= The material to go with the postGlow shader - postGlow.material.xml|&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;
&amp;lt;Material&amp;gt;&lt;br /&gt;
	&amp;lt;Shader source=&amp;quot;postGlow.shader.xml&amp;quot;/&amp;gt;&lt;br /&gt;
&amp;lt;/Material&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;}}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{{CppSourceCode|&lt;br /&gt;
description= This context is designed to be added to the original skinning shaders - skinning.shader.xml and skinning_metal.shader.xml|&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;
&amp;lt;Context id=&amp;quot;GLOWMASK&amp;quot;&amp;gt;	&lt;br /&gt;
	&amp;lt;!-- This material does not glow - output black pixels --&amp;gt;&lt;br /&gt;
	&amp;lt;VertexShader&amp;gt;&lt;br /&gt;
		&amp;lt;InsCode code=&amp;quot;utilityLib/vertCommon.glsl&amp;quot; /&amp;gt;&lt;br /&gt;
		&amp;lt;InsCode code=&amp;quot;utilityLib/vertSkinning.glsl&amp;quot; /&amp;gt;&lt;br /&gt;
		&amp;lt;DefCode&amp;gt;&lt;br /&gt;
		&amp;lt;![CDATA[&lt;br /&gt;
			void main( void )&lt;br /&gt;
			{&lt;br /&gt;
				// Calculate skinning matrices&lt;br /&gt;
				mat4 skinningMat = calcSkinningMat();&lt;br /&gt;
				mat3 skinningMatVec = getSkinningMatVec( skinningMat );&lt;br /&gt;
				// Calculate world space position&lt;br /&gt;
				vec4 pos = calcWorldPos( skinPos( gl_Vertex, skinningMat ) );&lt;br /&gt;
				// Calculate clip space position&lt;br /&gt;
				gl_Position = gl_ModelViewProjectionMatrix * pos;&lt;br /&gt;
			}&lt;br /&gt;
		]]&amp;gt;&lt;br /&gt;
		&amp;lt;/DefCode&amp;gt;&lt;br /&gt;
	&amp;lt;/VertexShader&amp;gt;&lt;br /&gt;
	&lt;br /&gt;
	&amp;lt;FragmentShader&amp;gt;&lt;br /&gt;
		&amp;lt;InsCode code=&amp;quot;utilityLib/fragLighting.glsl&amp;quot; /&amp;gt;&lt;br /&gt;
		&amp;lt;DefCode&amp;gt;&lt;br /&gt;
		&amp;lt;![CDATA[&lt;br /&gt;
			void main( void )&lt;br /&gt;
			{&lt;br /&gt;
				gl_FragColor.rgb = vec3(0,0,0);&lt;br /&gt;
			}&lt;br /&gt;
		]]&amp;gt;&lt;br /&gt;
		&amp;lt;/DefCode&amp;gt;&lt;br /&gt;
	&amp;lt;/FragmentShader&amp;gt;&lt;br /&gt;
&amp;lt;/Context&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;}}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Example Result == &lt;br /&gt;
[http://horde3d.org/forums/download/file.php?id=51 Click here to view]&lt;br /&gt;
&lt;br /&gt;
== To-Do List for this Article ==&lt;br /&gt;
- Write the article, describe the code and pipeline changes required&amp;lt;BR/&amp;gt;&lt;br /&gt;
- Add pictures&amp;lt;BR/&amp;gt;&lt;br /&gt;
- Ask for permission to upload a ZIP of my finished xml/tga files ;)&amp;lt;BR/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
}}&lt;br /&gt;
|  valign=&amp;quot;top&amp;quot; | {{Extension_Summary&lt;br /&gt;
|name = Technique - Glow&lt;br /&gt;
|screenshot = todo.jpg&lt;br /&gt;
|description = Using an alpha channel to add emissive bloom.&lt;br /&gt;
|version = 1.0&lt;br /&gt;
|horde3dversion = 1.0 beta&lt;br /&gt;
|released = 2008-08-06&lt;br /&gt;
|author = [http://www.horde3d.org/forums/memberlist.php?mode=viewprofile&amp;amp;u=30 DarkAngel]|&lt;br /&gt;
}}&lt;br /&gt;
|}&lt;br /&gt;
[[category: Technique]]&lt;/div&gt;</summary>
		<author><name>Darkangel</name></author>	</entry>

	<entry>
		<id>http://horde3d.org/wiki/index.php?title=User_talk:Darkangel&amp;diff=296</id>
		<title>User talk:Darkangel</title>
		<link rel="alternate" type="text/html" href="http://horde3d.org/wiki/index.php?title=User_talk:Darkangel&amp;diff=296"/>
				<updated>2008-08-07T09:27:22Z</updated>
		
		<summary type="html">&lt;p&gt;Darkangel: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Feel free to add any comments on my contributions to this talk page&lt;br /&gt;
#[[Shading Technique - Gloss Mapping]]&lt;br /&gt;
#[[Shading Technique - Glow Mapping]]&lt;/div&gt;</summary>
		<author><name>Darkangel</name></author>	</entry>

	<entry>
		<id>http://horde3d.org/wiki/index.php?title=Shading_Technique_-_Glow_Mapping&amp;diff=295</id>
		<title>Shading Technique - Glow Mapping</title>
		<link rel="alternate" type="text/html" href="http://horde3d.org/wiki/index.php?title=Shading_Technique_-_Glow_Mapping&amp;diff=295"/>
				<updated>2008-08-07T09:12:24Z</updated>
		
		<summary type="html">&lt;p&gt;Darkangel: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{|  border=&amp;quot;0&amp;quot; &lt;br /&gt;
| {{ContentBlock|width=800|color=white&lt;br /&gt;
|content={{!!}}&lt;br /&gt;
&lt;br /&gt;
'''I'm in the process of writing this article - come back later!'''&lt;br /&gt;
&lt;br /&gt;
== Overview ==&lt;br /&gt;
For an in-depth overview of this technique, see the Gamasutra article [http://www.gamasutra.com/features/20040526/james_pfv.htm Real-Time Glow] by By Greg James and John O’Rorke.&lt;br /&gt;
&lt;br /&gt;
== Temporary code dump == &lt;br /&gt;
Until I finish writing this article, here's the undocumented code ;)&lt;br /&gt;
&lt;br /&gt;
'''Pipeline changes'''&lt;br /&gt;
&lt;br /&gt;
{{CppSourceCode|&lt;br /&gt;
description= Setup the RenderTargets. If this is for HDR, then these RenderTargets will already exist, so just change depthBuf to &amp;quot;true&amp;quot; on the first one|&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;
&amp;lt;stage id=&amp;quot;Glow&amp;quot;&amp;gt;&lt;br /&gt;
	&amp;lt;RenderTarget id=&amp;quot;BLURBUF1&amp;quot; depthBuf=&amp;quot;true&amp;quot;  numColBufs=&amp;quot;1&amp;quot; format=&amp;quot;RGBA8&amp;quot; bilinear=&amp;quot;true&amp;quot; scale=&amp;quot;0.25&amp;quot; /&amp;gt;&lt;br /&gt;
	&amp;lt;RenderTarget id=&amp;quot;BLURBUF2&amp;quot; depthBuf=&amp;quot;false&amp;quot; numColBufs=&amp;quot;1&amp;quot; format=&amp;quot;RGBA8&amp;quot; bilinear=&amp;quot;true&amp;quot; scale=&amp;quot;0.25&amp;quot; /&amp;gt;&lt;br /&gt;
&amp;lt;/stage&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;}}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{{CppSourceCode|&lt;br /&gt;
description= insert this new stage after the &amp;quot;Geometry&amp;quot; stage.|&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;
&amp;lt;stage id=&amp;quot;Glow&amp;quot;&amp;gt;&lt;br /&gt;
	&amp;lt;SwitchTarget target=&amp;quot;BLURBUF1&amp;quot; /&amp;gt;			&lt;br /&gt;
	&amp;lt;ClearTarget depthBuf=&amp;quot;true&amp;quot; colBuf0=&amp;quot;true&amp;quot; /&amp;gt;&lt;br /&gt;
	&amp;lt;DrawGeometry context=&amp;quot;GLOWMASK&amp;quot; /&amp;gt;&lt;br /&gt;
	&lt;br /&gt;
	&amp;lt;!-- Repeat these steps as many times as you like, it makes the bloom softer --&amp;gt;&lt;br /&gt;
	&amp;lt;SwitchTarget target=&amp;quot;BLURBUF2&amp;quot; /&amp;gt;&lt;br /&gt;
	&amp;lt;BindBuffer texUnit=&amp;quot;0&amp;quot; target=&amp;quot;BLURBUF1&amp;quot; bufIndex=&amp;quot;0&amp;quot; /&amp;gt;&lt;br /&gt;
	&amp;lt;DrawQuad   material=&amp;quot;postGlow.material.xml&amp;quot; context=&amp;quot;BLURV&amp;quot; /&amp;gt;&lt;br /&gt;
	&amp;lt;SwitchTarget target=&amp;quot;BLURBUF1&amp;quot; /&amp;gt;&lt;br /&gt;
	&amp;lt;BindBuffer texUnit=&amp;quot;0&amp;quot; target=&amp;quot;BLURBUF2&amp;quot; bufIndex=&amp;quot;0&amp;quot; /&amp;gt;&lt;br /&gt;
	&amp;lt;DrawQuad   material=&amp;quot;postGlow.material.xml&amp;quot; context=&amp;quot;BLURH&amp;quot; /&amp;gt;&lt;br /&gt;
	&lt;br /&gt;
	&amp;lt;SwitchTarget target=&amp;quot;BLURBUF2&amp;quot; /&amp;gt;&lt;br /&gt;
	&amp;lt;BindBuffer texUnit=&amp;quot;0&amp;quot; target=&amp;quot;BLURBUF1&amp;quot; bufIndex=&amp;quot;0&amp;quot; /&amp;gt;&lt;br /&gt;
	&amp;lt;DrawQuad   material=&amp;quot;postGlow.material.xml&amp;quot; context=&amp;quot;BLURV&amp;quot; /&amp;gt;&lt;br /&gt;
	&amp;lt;SwitchTarget target=&amp;quot;BLURBUF1&amp;quot; /&amp;gt;&lt;br /&gt;
	&amp;lt;BindBuffer texUnit=&amp;quot;0&amp;quot; target=&amp;quot;BLURBUF2&amp;quot; bufIndex=&amp;quot;0&amp;quot; /&amp;gt;&lt;br /&gt;
	&amp;lt;DrawQuad   material=&amp;quot;postGlow.material.xml&amp;quot; context=&amp;quot;BLURH&amp;quot; /&amp;gt;&lt;br /&gt;
	&lt;br /&gt;
	&amp;lt;SwitchTarget target=&amp;quot;BLURBUF2&amp;quot; /&amp;gt;&lt;br /&gt;
	&amp;lt;BindBuffer texUnit=&amp;quot;0&amp;quot; target=&amp;quot;BLURBUF1&amp;quot; bufIndex=&amp;quot;0&amp;quot; /&amp;gt;&lt;br /&gt;
	&amp;lt;DrawQuad   material=&amp;quot;postGlow.material.xml&amp;quot; context=&amp;quot;BLURV&amp;quot; /&amp;gt;&lt;br /&gt;
	&amp;lt;SwitchTarget target=&amp;quot;BLURBUF1&amp;quot; /&amp;gt;&lt;br /&gt;
	&amp;lt;BindBuffer texUnit=&amp;quot;0&amp;quot; target=&amp;quot;BLURBUF2&amp;quot; bufIndex=&amp;quot;0&amp;quot; /&amp;gt;&lt;br /&gt;
	&amp;lt;DrawQuad   material=&amp;quot;postGlow.material.xml&amp;quot; context=&amp;quot;BLURH&amp;quot; /&amp;gt;&lt;br /&gt;
	&lt;br /&gt;
	&amp;lt;!-- In the HDR version, target should be set to &amp;quot;HDRBUF&amp;quot; --&amp;gt;&lt;br /&gt;
	&amp;lt;SwitchTarget target=&amp;quot;&amp;quot; /&amp;gt;&lt;br /&gt;
	&amp;lt;BindBuffer texUnit=&amp;quot;0&amp;quot; target=&amp;quot;BLURBUF1&amp;quot; bufIndex=&amp;quot;0&amp;quot; /&amp;gt;&lt;br /&gt;
	&amp;lt;DrawQuad material=&amp;quot;postGlow.material.xml&amp;quot; context=&amp;quot;FINALPASS&amp;quot; /&amp;gt;&lt;br /&gt;
&amp;lt;/stage&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;}}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''New shader code'''&lt;br /&gt;
&lt;br /&gt;
{{CppSourceCode|&lt;br /&gt;
description= This context is designed to be added to a copy of the parallax shader - parallax_glow.shader.xml|&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;
&amp;lt;Context id=&amp;quot;GLOWMASK&amp;quot;&amp;gt;	&lt;br /&gt;
	&amp;lt;!-- This material does glow - output colors masked by the alpha channel --&amp;gt;&lt;br /&gt;
	&amp;lt;VertexShader&amp;gt;&lt;br /&gt;
		&amp;lt;InsCode code=&amp;quot;utilityLib/vertCommon.glsl&amp;quot; /&amp;gt;&lt;br /&gt;
		&amp;lt;DefCode&amp;gt;&lt;br /&gt;
		&amp;lt;![CDATA[&lt;br /&gt;
			uniform vec3 viewer;&lt;br /&gt;
			attribute vec2 texCoords0;&lt;br /&gt;
			attribute vec3 normal, tangent, bitangent;&lt;br /&gt;
			varying vec3 eyeTS;&lt;br /&gt;
			varying vec2 texCoords;&lt;br /&gt;
			varying vec4 pos;&lt;br /&gt;
		&lt;br /&gt;
			void main( void )&lt;br /&gt;
			{&lt;br /&gt;
				// Transform tangent space basis&lt;br /&gt;
				vec3 tsbTangent = normalize( calcWorldVec( tangent ) );&lt;br /&gt;
				vec3 tsbBitangent = normalize( calcWorldVec( bitangent ) );&lt;br /&gt;
				vec3 tsbNormal = normalize( calcWorldVec( normal ) );&lt;br /&gt;
				&lt;br /&gt;
				// Calculate world space position&lt;br /&gt;
				pos = calcWorldPos( gl_Vertex );&lt;br /&gt;
				&lt;br /&gt;
				// Eye vector and eye vector in tangent space&lt;br /&gt;
				eyeTS = calcTanVec( viewer - pos.xyz, tsbTangent, tsbBitangent, tsbNormal );&lt;br /&gt;
		&lt;br /&gt;
				// Calculate texture coordinates and clip space position&lt;br /&gt;
				texCoords = texCoords0;&lt;br /&gt;
				gl_Position = gl_ModelViewProjectionMatrix * pos;&lt;br /&gt;
			}&lt;br /&gt;
		]]&amp;gt;&lt;br /&gt;
		&amp;lt;/DefCode&amp;gt;&lt;br /&gt;
	&amp;lt;/VertexShader&amp;gt;&lt;br /&gt;
	&lt;br /&gt;
	&amp;lt;FragmentShader&amp;gt;&lt;br /&gt;
		&amp;lt;DefCode&amp;gt;&lt;br /&gt;
		&amp;lt;![CDATA[&lt;br /&gt;
			uniform sampler2D tex0;&lt;br /&gt;
			varying vec3 eyeTS;&lt;br /&gt;
			varying vec2 texCoords;&lt;br /&gt;
			&lt;br /&gt;
			void main( void )&lt;br /&gt;
			{&lt;br /&gt;
				const float plxScale = 0.03;&lt;br /&gt;
				const float plxBias = -0.015;&lt;br /&gt;
				&lt;br /&gt;
				// Iterative parallax mapping&lt;br /&gt;
				vec3 newCoords = vec3( texCoords, 0 );&lt;br /&gt;
				vec3 eye = normalize( eyeTS );&lt;br /&gt;
				for( int i = 0; i &amp;lt; 4; ++i )&lt;br /&gt;
				{&lt;br /&gt;
					vec4 nmap = texture2D( tex0, texCoords.st );&lt;br /&gt;
					float height = nmap.a * plxScale + plxBias;&lt;br /&gt;
					newCoords += (height - newCoords.p) * nmap.z * eye;&lt;br /&gt;
				}&lt;br /&gt;
				&lt;br /&gt;
				vec4 glow = texture2D( tex0, newCoords.st ).rgba;&lt;br /&gt;
				glow *= glow.a;&lt;br /&gt;
				&lt;br /&gt;
				gl_FragColor = glow;&lt;br /&gt;
			}&lt;br /&gt;
		]]&amp;gt;&lt;br /&gt;
		&amp;lt;/DefCode&amp;gt;&lt;br /&gt;
	&amp;lt;/FragmentShader&amp;gt;&lt;br /&gt;
&amp;lt;/Context&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;}}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{{CppSourceCode|&lt;br /&gt;
description= This is a new shader, called postGlow.shader.xml|&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;
&amp;lt;Shader&amp;gt;&lt;br /&gt;
	&lt;br /&gt;
	&amp;lt;Context id=&amp;quot;BLURH&amp;quot;&amp;gt;&lt;br /&gt;
		&amp;lt;RenderConfig writeDepth=&amp;quot;false&amp;quot; /&amp;gt;&lt;br /&gt;
		&amp;lt;VertexShader&amp;gt;&lt;br /&gt;
			&amp;lt;DefCode&amp;gt;&lt;br /&gt;
			&amp;lt;![CDATA[&lt;br /&gt;
				varying vec2 texCoord;&lt;br /&gt;
				void main( void )&lt;br /&gt;
				{&lt;br /&gt;
					texCoord = gl_MultiTexCoord0.st; &lt;br /&gt;
					gl_Position = gl_ProjectionMatrix * gl_Vertex;&lt;br /&gt;
				}&lt;br /&gt;
			]]&amp;gt;&lt;br /&gt;
			&amp;lt;/DefCode&amp;gt;&lt;br /&gt;
		&amp;lt;/VertexShader&amp;gt;&lt;br /&gt;
		&amp;lt;FragmentShader&amp;gt;&lt;br /&gt;
			&amp;lt;InsCode code=&amp;quot;utilityLib/fragPostProcess.glsl&amp;quot; /&amp;gt;&lt;br /&gt;
			&amp;lt;DefCode&amp;gt;&lt;br /&gt;
			&amp;lt;![CDATA[&lt;br /&gt;
				uniform sampler2D tex;&lt;br /&gt;
				uniform vec2 frameBufSize;&lt;br /&gt;
				varying vec2 texCoord;&lt;br /&gt;
				void main( void )&lt;br /&gt;
				{	&lt;br /&gt;
					float halfPixel = 0.5 / frameBufSize.x;&lt;br /&gt;
					vec4 col  = texture2D( tex, texCoord + vec2( halfPixel,   0.0 ) );&lt;br /&gt;
					     col += texture2D( tex, texCoord - vec2( halfPixel,   0.0 ) );&lt;br /&gt;
					     col += texture2D( tex, texCoord + vec2( halfPixel*3.0, 0.0 ) );&lt;br /&gt;
					     col += texture2D( tex, texCoord - vec2( halfPixel*3.0, 0.0 ) );&lt;br /&gt;
					gl_FragColor = col * 0.25; &lt;br /&gt;
				}&lt;br /&gt;
			]]&amp;gt;&lt;br /&gt;
			&amp;lt;/DefCode&amp;gt;&lt;br /&gt;
		&amp;lt;/FragmentShader&amp;gt;&lt;br /&gt;
	&amp;lt;/Context&amp;gt;&lt;br /&gt;
	&amp;lt;Context id=&amp;quot;BLURV&amp;quot;&amp;gt;&lt;br /&gt;
		&amp;lt;RenderConfig writeDepth=&amp;quot;false&amp;quot; /&amp;gt;&lt;br /&gt;
		&amp;lt;VertexShader&amp;gt;&lt;br /&gt;
			&amp;lt;DefCode&amp;gt;&lt;br /&gt;
			&amp;lt;![CDATA[&lt;br /&gt;
				varying vec2 texCoord;&lt;br /&gt;
				void main( void )&lt;br /&gt;
				{&lt;br /&gt;
					texCoord = gl_MultiTexCoord0.st; &lt;br /&gt;
					gl_Position = gl_ProjectionMatrix * gl_Vertex;&lt;br /&gt;
				}&lt;br /&gt;
			]]&amp;gt;&lt;br /&gt;
			&amp;lt;/DefCode&amp;gt;&lt;br /&gt;
		&amp;lt;/VertexShader&amp;gt;&lt;br /&gt;
		&amp;lt;FragmentShader&amp;gt;&lt;br /&gt;
			&amp;lt;InsCode code=&amp;quot;utilityLib/fragPostProcess.glsl&amp;quot; /&amp;gt;&lt;br /&gt;
			&amp;lt;DefCode&amp;gt;&lt;br /&gt;
			&amp;lt;![CDATA[&lt;br /&gt;
				uniform sampler2D tex;&lt;br /&gt;
				uniform vec2 frameBufSize;&lt;br /&gt;
				varying vec2 texCoord;&lt;br /&gt;
				void main( void )&lt;br /&gt;
				{	&lt;br /&gt;
					float halfPixel = 0.5 / frameBufSize.y;&lt;br /&gt;
					vec4 col  = texture2D( tex, texCoord + vec2( 0.0, halfPixel   ) );&lt;br /&gt;
					     col += texture2D( tex, texCoord - vec2( 0.0, halfPixel   ) );&lt;br /&gt;
					     col += texture2D( tex, texCoord + vec2( 0.0, halfPixel*3.0 ) );&lt;br /&gt;
					     col += texture2D( tex, texCoord - vec2( 0.0, halfPixel*3.0 ) );&lt;br /&gt;
					gl_FragColor = col * 0.25;&lt;br /&gt;
				}&lt;br /&gt;
			]]&amp;gt;&lt;br /&gt;
			&amp;lt;/DefCode&amp;gt;&lt;br /&gt;
		&amp;lt;/FragmentShader&amp;gt;&lt;br /&gt;
	&amp;lt;/Context&amp;gt;&lt;br /&gt;
	&lt;br /&gt;
	&amp;lt;Context id=&amp;quot;FINALPASS&amp;quot;&amp;gt;&lt;br /&gt;
		&amp;lt;RenderConfig writeDepth=&amp;quot;false&amp;quot; blendMode=&amp;quot;ADD&amp;quot; /&amp;gt;&lt;br /&gt;
		&lt;br /&gt;
		&amp;lt;VertexShader&amp;gt;&lt;br /&gt;
			&amp;lt;DefCode&amp;gt;&lt;br /&gt;
			&amp;lt;![CDATA[&lt;br /&gt;
				varying vec2 texCoord;&lt;br /&gt;
				&lt;br /&gt;
				void main( void )&lt;br /&gt;
				{&lt;br /&gt;
					texCoord = gl_MultiTexCoord0.st; &lt;br /&gt;
					gl_Position = gl_ProjectionMatrix * gl_Vertex;&lt;br /&gt;
				}&lt;br /&gt;
			]]&amp;gt;&lt;br /&gt;
			&amp;lt;/DefCode&amp;gt;&lt;br /&gt;
		&amp;lt;/VertexShader&amp;gt;&lt;br /&gt;
		&lt;br /&gt;
		&amp;lt;FragmentShader&amp;gt;&lt;br /&gt;
			&amp;lt;DefCode&amp;gt;&lt;br /&gt;
			&amp;lt;![CDATA[&lt;br /&gt;
				uniform sampler2D tex0, tex1;&lt;br /&gt;
				uniform vec2 frameBufSize;&lt;br /&gt;
				uniform vec4 hdrParams;&lt;br /&gt;
				varying vec2 texCoord;&lt;br /&gt;
				&lt;br /&gt;
				void main( void )&lt;br /&gt;
				{&lt;br /&gt;
					gl_FragColor = texture2D( tex0, texCoord );	// Glow color&lt;br /&gt;
				}&lt;br /&gt;
			]]&amp;gt;&lt;br /&gt;
			&amp;lt;/DefCode&amp;gt;&lt;br /&gt;
		&amp;lt;/FragmentShader&amp;gt;&lt;br /&gt;
	&amp;lt;/Context&amp;gt;&lt;br /&gt;
&amp;lt;/Shader&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;}}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{{CppSourceCode|&lt;br /&gt;
description= The material to go with the postGlow shader - postGlow.material.xml|&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;
&amp;lt;Material&amp;gt;&lt;br /&gt;
	&amp;lt;Shader source=&amp;quot;postGlow.shader.xml&amp;quot;/&amp;gt;&lt;br /&gt;
&amp;lt;/Material&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;}}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{{CppSourceCode|&lt;br /&gt;
description= This context is designed to be added to the original skinning shaders - skinning.shader.xml and skinning_metal.shader.xml|&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;
&amp;lt;Context id=&amp;quot;GLOWMASK&amp;quot;&amp;gt;	&lt;br /&gt;
	&amp;lt;!-- This material does not glow - output black pixels --&amp;gt;&lt;br /&gt;
	&amp;lt;VertexShader&amp;gt;&lt;br /&gt;
		&amp;lt;InsCode code=&amp;quot;utilityLib/vertCommon.glsl&amp;quot; /&amp;gt;&lt;br /&gt;
		&amp;lt;InsCode code=&amp;quot;utilityLib/vertSkinning.glsl&amp;quot; /&amp;gt;&lt;br /&gt;
		&amp;lt;DefCode&amp;gt;&lt;br /&gt;
		&amp;lt;![CDATA[&lt;br /&gt;
			void main( void )&lt;br /&gt;
			{&lt;br /&gt;
				// Calculate skinning matrices&lt;br /&gt;
				mat4 skinningMat = calcSkinningMat();&lt;br /&gt;
				mat3 skinningMatVec = getSkinningMatVec( skinningMat );&lt;br /&gt;
				// Calculate world space position&lt;br /&gt;
				vec4 pos = calcWorldPos( skinPos( gl_Vertex, skinningMat ) );&lt;br /&gt;
				// Calculate clip space position&lt;br /&gt;
				gl_Position = gl_ModelViewProjectionMatrix * pos;&lt;br /&gt;
			}&lt;br /&gt;
		]]&amp;gt;&lt;br /&gt;
		&amp;lt;/DefCode&amp;gt;&lt;br /&gt;
	&amp;lt;/VertexShader&amp;gt;&lt;br /&gt;
	&lt;br /&gt;
	&amp;lt;FragmentShader&amp;gt;&lt;br /&gt;
		&amp;lt;InsCode code=&amp;quot;utilityLib/fragLighting.glsl&amp;quot; /&amp;gt;&lt;br /&gt;
		&amp;lt;DefCode&amp;gt;&lt;br /&gt;
		&amp;lt;![CDATA[&lt;br /&gt;
			void main( void )&lt;br /&gt;
			{&lt;br /&gt;
				gl_FragColor.rgb = vec3(0,0,0);&lt;br /&gt;
			}&lt;br /&gt;
		]]&amp;gt;&lt;br /&gt;
		&amp;lt;/DefCode&amp;gt;&lt;br /&gt;
	&amp;lt;/FragmentShader&amp;gt;&lt;br /&gt;
&amp;lt;/Context&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;}}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Example Result == &lt;br /&gt;
[http://horde3d.org/forums/download/file.php?id=51 Click here to view]&lt;br /&gt;
&lt;br /&gt;
== To-Do List for this Article ==&lt;br /&gt;
- Write the article, describe the code and pipeline changes required&amp;lt;BR/&amp;gt;&lt;br /&gt;
- Add pictures&amp;lt;BR/&amp;gt;&lt;br /&gt;
- Ask for permission to upload a ZIP of my finished xml/tga files ;)&amp;lt;BR/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
}}&lt;br /&gt;
|  valign=&amp;quot;top&amp;quot; | {{Extension_Summary&lt;br /&gt;
|name = Technique - Glow&lt;br /&gt;
|screenshot = todo.jpg&lt;br /&gt;
|description = Using an alpha channel to add emissive bloom.&lt;br /&gt;
|version = 1.0&lt;br /&gt;
|horde3dversion = 1.0 beta&lt;br /&gt;
|released = 2008-08-06&lt;br /&gt;
|author = [http://www.horde3d.org/forums/memberlist.php?mode=viewprofile&amp;amp;u=30 DarkAngel]|&lt;br /&gt;
}}&lt;br /&gt;
|}&lt;br /&gt;
[[category: Technique]]&lt;/div&gt;</summary>
		<author><name>Darkangel</name></author>	</entry>

	<entry>
		<id>http://horde3d.org/wiki/index.php?title=Shading_Technique_-_Glow_Mapping&amp;diff=294</id>
		<title>Shading Technique - Glow Mapping</title>
		<link rel="alternate" type="text/html" href="http://horde3d.org/wiki/index.php?title=Shading_Technique_-_Glow_Mapping&amp;diff=294"/>
				<updated>2008-08-07T09:09:56Z</updated>
		
		<summary type="html">&lt;p&gt;Darkangel: added a dump of my code until I actually finish writing this&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{|  border=&amp;quot;0&amp;quot; &lt;br /&gt;
| {{ContentBlock|width=800|color=white&lt;br /&gt;
|content={{!!}}&lt;br /&gt;
&lt;br /&gt;
'''I'm in the process of writing this article - come back later!'''&lt;br /&gt;
&lt;br /&gt;
== Overview ==&lt;br /&gt;
For an in-depth overview of this technique, see the Gamasutra article [http://www.gamasutra.com/features/20040526/james_pfv.htm Real-Time Glow] by By Greg James and John O’Rorke.&lt;br /&gt;
&lt;br /&gt;
== Temporary code dump == &lt;br /&gt;
Until I finish writing this article, here's the undocumented code ;)&lt;br /&gt;
&lt;br /&gt;
'''Pipeline changes'''&lt;br /&gt;
&lt;br /&gt;
{{CppSourceCode|&lt;br /&gt;
description= Setup the RenderTargets. If this is for HDR, then these RenderTargets will already exist, so just change depthBuf to &amp;quot;true&amp;quot; on the first one|&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;
&amp;lt;stage id=&amp;quot;Glow&amp;quot;&amp;gt;&lt;br /&gt;
	&amp;lt;RenderTarget id=&amp;quot;BLURBUF1&amp;quot; depthBuf=&amp;quot;true&amp;quot;  numColBufs=&amp;quot;1&amp;quot; format=&amp;quot;RGBA8&amp;quot; bilinear=&amp;quot;true&amp;quot; scale=&amp;quot;0.25&amp;quot; /&amp;gt;&lt;br /&gt;
	&amp;lt;RenderTarget id=&amp;quot;BLURBUF2&amp;quot; depthBuf=&amp;quot;false&amp;quot; numColBufs=&amp;quot;1&amp;quot; format=&amp;quot;RGBA8&amp;quot; bilinear=&amp;quot;true&amp;quot; scale=&amp;quot;0.25&amp;quot; /&amp;gt;&lt;br /&gt;
&amp;lt;/stage&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;}}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{{CppSourceCode|&lt;br /&gt;
description= insert this new stage after the &amp;quot;Geometry&amp;quot; stage.|&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;
&amp;lt;stage id=&amp;quot;Glow&amp;quot;&amp;gt;&lt;br /&gt;
	&amp;lt;SwitchTarget target=&amp;quot;BLURBUF1&amp;quot; /&amp;gt;			&lt;br /&gt;
	&amp;lt;ClearTarget depthBuf=&amp;quot;true&amp;quot; colBuf0=&amp;quot;true&amp;quot; /&amp;gt;&lt;br /&gt;
	&amp;lt;DrawGeometry context=&amp;quot;GLOWMASK&amp;quot; /&amp;gt;&lt;br /&gt;
	&lt;br /&gt;
	&amp;lt;!-- Repeat these steps as many times as you like, it makes the bloom softer --&amp;gt;&lt;br /&gt;
	&amp;lt;SwitchTarget target=&amp;quot;BLURBUF2&amp;quot; /&amp;gt;&lt;br /&gt;
	&amp;lt;BindBuffer texUnit=&amp;quot;0&amp;quot; target=&amp;quot;BLURBUF1&amp;quot; bufIndex=&amp;quot;0&amp;quot; /&amp;gt;&lt;br /&gt;
	&amp;lt;DrawQuad   material=&amp;quot;postGlow.material.xml&amp;quot; context=&amp;quot;BLURV&amp;quot; /&amp;gt;&lt;br /&gt;
	&amp;lt;SwitchTarget target=&amp;quot;BLURBUF1&amp;quot; /&amp;gt;&lt;br /&gt;
	&amp;lt;BindBuffer texUnit=&amp;quot;0&amp;quot; target=&amp;quot;BLURBUF2&amp;quot; bufIndex=&amp;quot;0&amp;quot; /&amp;gt;&lt;br /&gt;
	&amp;lt;DrawQuad   material=&amp;quot;postGlow.material.xml&amp;quot; context=&amp;quot;BLURH&amp;quot; /&amp;gt;&lt;br /&gt;
	&lt;br /&gt;
	&amp;lt;SwitchTarget target=&amp;quot;BLURBUF2&amp;quot; /&amp;gt;&lt;br /&gt;
	&amp;lt;BindBuffer texUnit=&amp;quot;0&amp;quot; target=&amp;quot;BLURBUF1&amp;quot; bufIndex=&amp;quot;0&amp;quot; /&amp;gt;&lt;br /&gt;
	&amp;lt;DrawQuad   material=&amp;quot;postGlow.material.xml&amp;quot; context=&amp;quot;BLURV&amp;quot; /&amp;gt;&lt;br /&gt;
	&amp;lt;SwitchTarget target=&amp;quot;BLURBUF1&amp;quot; /&amp;gt;&lt;br /&gt;
	&amp;lt;BindBuffer texUnit=&amp;quot;0&amp;quot; target=&amp;quot;BLURBUF2&amp;quot; bufIndex=&amp;quot;0&amp;quot; /&amp;gt;&lt;br /&gt;
	&amp;lt;DrawQuad   material=&amp;quot;postGlow.material.xml&amp;quot; context=&amp;quot;BLURH&amp;quot; /&amp;gt;&lt;br /&gt;
	&lt;br /&gt;
	&amp;lt;SwitchTarget target=&amp;quot;BLURBUF2&amp;quot; /&amp;gt;&lt;br /&gt;
	&amp;lt;BindBuffer texUnit=&amp;quot;0&amp;quot; target=&amp;quot;BLURBUF1&amp;quot; bufIndex=&amp;quot;0&amp;quot; /&amp;gt;&lt;br /&gt;
	&amp;lt;DrawQuad   material=&amp;quot;postGlow.material.xml&amp;quot; context=&amp;quot;BLURV&amp;quot; /&amp;gt;&lt;br /&gt;
	&amp;lt;SwitchTarget target=&amp;quot;BLURBUF1&amp;quot; /&amp;gt;&lt;br /&gt;
	&amp;lt;BindBuffer texUnit=&amp;quot;0&amp;quot; target=&amp;quot;BLURBUF2&amp;quot; bufIndex=&amp;quot;0&amp;quot; /&amp;gt;&lt;br /&gt;
	&amp;lt;DrawQuad   material=&amp;quot;postGlow.material.xml&amp;quot; context=&amp;quot;BLURH&amp;quot; /&amp;gt;&lt;br /&gt;
	&lt;br /&gt;
	&amp;lt;!-- In the HDR version, target should be set to &amp;quot;HDRBUF&amp;quot; --&amp;gt;&lt;br /&gt;
	&amp;lt;SwitchTarget target=&amp;quot;&amp;quot; /&amp;gt;&lt;br /&gt;
	&amp;lt;BindBuffer texUnit=&amp;quot;0&amp;quot; target=&amp;quot;BLURBUF1&amp;quot; bufIndex=&amp;quot;0&amp;quot; /&amp;gt;&lt;br /&gt;
	&amp;lt;DrawQuad material=&amp;quot;postGlow.material.xml&amp;quot; context=&amp;quot;FINALPASS&amp;quot; /&amp;gt;&lt;br /&gt;
&amp;lt;/stage&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;}}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''New shader code'''&lt;br /&gt;
&lt;br /&gt;
{{CppSourceCode|&lt;br /&gt;
description= This context is designed to be added to a copy of the parallax shader - parallax_glow.shader.xml|&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;
&amp;lt;Context id=&amp;quot;GLOWMASK&amp;quot;&amp;gt;	&lt;br /&gt;
	&amp;lt;!-- This material does glow - output colors masked by the alpha channel --&amp;gt;&lt;br /&gt;
	&amp;lt;VertexShader&amp;gt;&lt;br /&gt;
		&amp;lt;InsCode code=&amp;quot;utilityLib/vertCommon.glsl&amp;quot; /&amp;gt;&lt;br /&gt;
		&amp;lt;DefCode&amp;gt;&lt;br /&gt;
		&amp;lt;![CDATA[&lt;br /&gt;
			uniform vec3 viewer;&lt;br /&gt;
			attribute vec2 texCoords0;&lt;br /&gt;
			attribute vec3 normal, tangent, bitangent;&lt;br /&gt;
			varying vec3 eyeTS;&lt;br /&gt;
			varying vec2 texCoords;&lt;br /&gt;
			varying vec4 pos;&lt;br /&gt;
		&lt;br /&gt;
			void main( void )&lt;br /&gt;
			{&lt;br /&gt;
				// Transform tangent space basis&lt;br /&gt;
				vec3 tsbTangent = normalize( calcWorldVec( tangent ) );&lt;br /&gt;
				vec3 tsbBitangent = normalize( calcWorldVec( bitangent ) );&lt;br /&gt;
				vec3 tsbNormal = normalize( calcWorldVec( normal ) );&lt;br /&gt;
				&lt;br /&gt;
				// Calculate world space position&lt;br /&gt;
				pos = calcWorldPos( gl_Vertex );&lt;br /&gt;
				&lt;br /&gt;
				// Eye vector and eye vector in tangent space&lt;br /&gt;
				eyeTS = calcTanVec( viewer - pos.xyz, tsbTangent, tsbBitangent, tsbNormal );&lt;br /&gt;
		&lt;br /&gt;
				// Calculate texture coordinates and clip space position&lt;br /&gt;
				texCoords = texCoords0;&lt;br /&gt;
				gl_Position = gl_ModelViewProjectionMatrix * pos;&lt;br /&gt;
			}&lt;br /&gt;
		]]&amp;gt;&lt;br /&gt;
		&amp;lt;/DefCode&amp;gt;&lt;br /&gt;
	&amp;lt;/VertexShader&amp;gt;&lt;br /&gt;
	&lt;br /&gt;
	&amp;lt;FragmentShader&amp;gt;&lt;br /&gt;
		&amp;lt;DefCode&amp;gt;&lt;br /&gt;
		&amp;lt;![CDATA[&lt;br /&gt;
			uniform sampler2D tex0;&lt;br /&gt;
			varying vec3 eyeTS;&lt;br /&gt;
			varying vec2 texCoords;&lt;br /&gt;
			&lt;br /&gt;
			void main( void )&lt;br /&gt;
			{&lt;br /&gt;
				const float plxScale = 0.03;&lt;br /&gt;
				const float plxBias = -0.015;&lt;br /&gt;
				&lt;br /&gt;
				// Iterative parallax mapping&lt;br /&gt;
				vec3 newCoords = vec3( texCoords, 0 );&lt;br /&gt;
				vec3 eye = normalize( eyeTS );&lt;br /&gt;
				for( int i = 0; i &amp;lt; 4; ++i )&lt;br /&gt;
				{&lt;br /&gt;
					vec4 nmap = texture2D( tex0, texCoords.st );&lt;br /&gt;
					float height = nmap.a * plxScale + plxBias;&lt;br /&gt;
					newCoords += (height - newCoords.p) * nmap.z * eye;&lt;br /&gt;
				}&lt;br /&gt;
				&lt;br /&gt;
				vec4 glow = texture2D( tex0, newCoords.st ).rgba;&lt;br /&gt;
				glow *= glow.a;&lt;br /&gt;
				&lt;br /&gt;
				gl_FragColor = glow;&lt;br /&gt;
			}&lt;br /&gt;
		]]&amp;gt;&lt;br /&gt;
		&amp;lt;/DefCode&amp;gt;&lt;br /&gt;
	&amp;lt;/FragmentShader&amp;gt;&lt;br /&gt;
&amp;lt;/Context&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;}}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{{CppSourceCode|&lt;br /&gt;
description= This context is designed to be added to the original skinning shaders - skinning.shader.xml and skinning_metal.shader.xml|&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;
&amp;lt;Context id=&amp;quot;GLOWMASK&amp;quot;&amp;gt;	&lt;br /&gt;
	&amp;lt;!-- This material does not glow - output black pixels --&amp;gt;&lt;br /&gt;
	&amp;lt;VertexShader&amp;gt;&lt;br /&gt;
		&amp;lt;InsCode code=&amp;quot;utilityLib/vertCommon.glsl&amp;quot; /&amp;gt;&lt;br /&gt;
		&amp;lt;InsCode code=&amp;quot;utilityLib/vertSkinning.glsl&amp;quot; /&amp;gt;&lt;br /&gt;
		&amp;lt;DefCode&amp;gt;&lt;br /&gt;
		&amp;lt;![CDATA[&lt;br /&gt;
			void main( void )&lt;br /&gt;
			{&lt;br /&gt;
				// Calculate skinning matrices&lt;br /&gt;
				mat4 skinningMat = calcSkinningMat();&lt;br /&gt;
				mat3 skinningMatVec = getSkinningMatVec( skinningMat );&lt;br /&gt;
				// Calculate world space position&lt;br /&gt;
				vec4 pos = calcWorldPos( skinPos( gl_Vertex, skinningMat ) );&lt;br /&gt;
				// Calculate clip space position&lt;br /&gt;
				gl_Position = gl_ModelViewProjectionMatrix * pos;&lt;br /&gt;
			}&lt;br /&gt;
		]]&amp;gt;&lt;br /&gt;
		&amp;lt;/DefCode&amp;gt;&lt;br /&gt;
	&amp;lt;/VertexShader&amp;gt;&lt;br /&gt;
	&lt;br /&gt;
	&amp;lt;FragmentShader&amp;gt;&lt;br /&gt;
		&amp;lt;InsCode code=&amp;quot;utilityLib/fragLighting.glsl&amp;quot; /&amp;gt;&lt;br /&gt;
		&amp;lt;DefCode&amp;gt;&lt;br /&gt;
		&amp;lt;![CDATA[&lt;br /&gt;
			void main( void )&lt;br /&gt;
			{&lt;br /&gt;
				gl_FragColor.rgb = vec3(0,0,0);&lt;br /&gt;
			}&lt;br /&gt;
		]]&amp;gt;&lt;br /&gt;
		&amp;lt;/DefCode&amp;gt;&lt;br /&gt;
	&amp;lt;/FragmentShader&amp;gt;&lt;br /&gt;
&amp;lt;/Context&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;}}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Example Result == &lt;br /&gt;
[http://horde3d.org/forums/download/file.php?id=51 Click here to view]&lt;br /&gt;
&lt;br /&gt;
== To-Do List for this Article ==&lt;br /&gt;
- Write the article, describe the code and pipeline changes required&amp;lt;BR/&amp;gt;&lt;br /&gt;
- Add pictures&amp;lt;BR/&amp;gt;&lt;br /&gt;
- Ask for permission to upload a ZIP of my finished xml/tga files ;)&amp;lt;BR/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
}}&lt;br /&gt;
|  valign=&amp;quot;top&amp;quot; | {{Extension_Summary&lt;br /&gt;
|name = Technique - Glow&lt;br /&gt;
|screenshot = todo.jpg&lt;br /&gt;
|description = Using an alpha channel to add emissive bloom.&lt;br /&gt;
|version = 1.0&lt;br /&gt;
|horde3dversion = 1.0 beta&lt;br /&gt;
|released = 2008-08-06&lt;br /&gt;
|author = [http://www.horde3d.org/forums/memberlist.php?mode=viewprofile&amp;amp;u=30 DarkAngel]|&lt;br /&gt;
}}&lt;br /&gt;
|}&lt;br /&gt;
[[category: Technique]]&lt;/div&gt;</summary>
		<author><name>Darkangel</name></author>	</entry>

	<entry>
		<id>http://horde3d.org/wiki/index.php?title=Shading_Technique_-_Glow_Mapping&amp;diff=293</id>
		<title>Shading Technique - Glow Mapping</title>
		<link rel="alternate" type="text/html" href="http://horde3d.org/wiki/index.php?title=Shading_Technique_-_Glow_Mapping&amp;diff=293"/>
				<updated>2008-08-06T10:54:22Z</updated>
		
		<summary type="html">&lt;p&gt;Darkangel: draft&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{|  border=&amp;quot;0&amp;quot; &lt;br /&gt;
| {{ContentBlock|width=800|color=white&lt;br /&gt;
|content={{!!}}&lt;br /&gt;
&lt;br /&gt;
'''I'm in the process of writing this article - come back later!'''&lt;br /&gt;
&lt;br /&gt;
== Overview ==&lt;br /&gt;
For an in-depth overview of this technique, see the Gamasutra article [http://www.gamasutra.com/features/20040526/james_pfv.htm Real-Time Glow] by By Greg James and John O’Rorke.&lt;br /&gt;
&lt;br /&gt;
== Example Result == &lt;br /&gt;
[http://horde3d.org/forums/download/file.php?id=51 Click here to view]&lt;br /&gt;
&lt;br /&gt;
== To-Do List for this Article ==&lt;br /&gt;
- Write the article, describe the code and pipeline changes required&amp;lt;BR/&amp;gt;&lt;br /&gt;
- Add pictures&amp;lt;BR/&amp;gt;&lt;br /&gt;
- Ask for permission to upload a ZIP of my finished xml/tga files ;)&amp;lt;BR/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
}}&lt;br /&gt;
|  valign=&amp;quot;top&amp;quot; | {{Extension_Summary&lt;br /&gt;
|name = Technique - Glow&lt;br /&gt;
|screenshot = todo.jpg&lt;br /&gt;
|description = Using an alpha channel to add emissive bloom.&lt;br /&gt;
|version = 1.0&lt;br /&gt;
|horde3dversion = 1.0 beta&lt;br /&gt;
|released = 2008-08-06&lt;br /&gt;
|author = [http://www.horde3d.org/forums/memberlist.php?mode=viewprofile&amp;amp;u=30 DarkAngel]|&lt;br /&gt;
}}&lt;br /&gt;
|}&lt;br /&gt;
[[category: Technique]]&lt;/div&gt;</summary>
		<author><name>Darkangel</name></author>	</entry>

	<entry>
		<id>http://horde3d.org/wiki/index.php?title=Shading_Technique_-_Gloss_Mapping&amp;diff=292</id>
		<title>Shading Technique - Gloss Mapping</title>
		<link rel="alternate" type="text/html" href="http://horde3d.org/wiki/index.php?title=Shading_Technique_-_Gloss_Mapping&amp;diff=292"/>
				<updated>2008-08-06T10:41:58Z</updated>
		
		<summary type="html">&lt;p&gt;Darkangel: done&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{|  border=&amp;quot;0&amp;quot; &lt;br /&gt;
| {{ContentBlock|width=800|color=white&lt;br /&gt;
|content={{!!}}&lt;br /&gt;
&lt;br /&gt;
== Overview ==&lt;br /&gt;
'''What is a gloss map?''' a texture that describes whether a surface area is [http://en.wikipedia.org/wiki/Gloss_%28material_appearance%29 matte or gloss]. This texture is used as a [http://en.wikipedia.org/wiki/Masking_%28in_art%29 mask] for specular highlights.&lt;br /&gt;
&lt;br /&gt;
'''Why might you want to use this technique?'''&amp;lt;br/&amp;gt;&lt;br /&gt;
- On materials that visibly vary in &amp;quot;shininess&amp;quot;, such as reflective metal that is partially dirty. &amp;lt;br/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Requirements:'''&amp;lt;BR/&amp;gt;&lt;br /&gt;
- RGBA texture, with the RGB channels representing color (as usual) and the alpha channel representing the gloss map&amp;lt;BR/&amp;gt;&lt;br /&gt;
- Bright areas in the gloss map will by shiny, dark areas will be matte&amp;lt;BR/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== The Technique ==&lt;br /&gt;
Seeing as specular lighting is already present in the shaders that are bundled with a new Horde3D installation, adding in a specular mask is exceedingly simple.&lt;br /&gt;
&lt;br /&gt;
Only a few minor adjustments are required, in theory all we need to do is read the alpha channel from our texture and input that data into the specular lighting equations. I will make a modified version of the parallax shader to demonstrate how to make these additions. I'll make the changes for both the deferred and forward shading versions of the code.&lt;br /&gt;
&lt;br /&gt;
The first step is the same for both the deferred and forward versions (i.e. the ATTRIBPASS and the LIGHTING contexts, respectively).&lt;br /&gt;
{{CppSourceCode|&lt;br /&gt;
description= GLSL Code to be modified in both ATTRIBPASS and LIGHTING.|&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;
//This line reads the RGB values of our texture, comment it out:&lt;br /&gt;
//vec3 albedo = texture2D( tex0, newCoords.st ).rgb;&lt;br /&gt;
//And then replace it with this code that also reads the alpha channel:&lt;br /&gt;
vec4 albedo_gloss = texture2D( tex0, newCoords.st ).rgba;&lt;br /&gt;
vec3 albedo = albedo_gloss.rgb;&lt;br /&gt;
float gloss = albedo_gloss.a;&lt;br /&gt;
&amp;lt;/source&amp;gt;}}&lt;br /&gt;
&lt;br /&gt;
This next change is for the forward shading version only.&lt;br /&gt;
{{CppSourceCode|&lt;br /&gt;
description= GLSL Code to be modified in LIGHTING.|&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;
//This line of code performs the lighting equation. The first hard-coded values of 0.3 is the specular mask value.&lt;br /&gt;
//gl_FragColor.rgb =&lt;br /&gt;
//	calcPhongSpotLight( newPos, normalize( normal ), albedo, 0.3, 16.0, -vsPos.z, 0.3 );&lt;br /&gt;
//Change the first &amp;quot;0.3&amp;quot; value to &amp;quot;gloss&amp;quot;, Like this:&lt;br /&gt;
gl_FragColor.rgb =&lt;br /&gt;
	calcPhongSpotLight( newPos, normalize( normal ), albedo, gloss, 16.0, -vsPos.z, 0.3 );&lt;br /&gt;
&amp;lt;/source&amp;gt;}}&lt;br /&gt;
&lt;br /&gt;
This next change is for the deferred shading version only.&lt;br /&gt;
{{CppSourceCode|&lt;br /&gt;
description= GLSL Code to be modified in ATTRIBPASS.|&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;
//This line of code saves the material properties. The hard-coded value of 0.3 is the specular mask value.&lt;br /&gt;
//setSpecMask( 0.3 );&lt;br /&gt;
//Change the &amp;quot;0.3&amp;quot; value to &amp;quot;gloss&amp;quot;, Like this:&lt;br /&gt;
setSpecMask( gloss );&lt;br /&gt;
&amp;lt;/source&amp;gt;}}&lt;br /&gt;
&lt;br /&gt;
== Example Result == &lt;br /&gt;
[http://horde3d.org/forums/download/file.php?id=50 Click here to view]&lt;br /&gt;
&lt;br /&gt;
== To-Do List for this Article ==&lt;br /&gt;
- Add pictures&amp;lt;BR/&amp;gt;&lt;br /&gt;
- Ask for permission to upload a ZIP of my finished xml/tga files ;)&amp;lt;BR/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
}}&lt;br /&gt;
|  valign=&amp;quot;top&amp;quot; | {{Extension_Summary&lt;br /&gt;
|name = Technique - Gloss mapping&lt;br /&gt;
|screenshot = todo.jpg&lt;br /&gt;
|description = Using an alpha channel to mask specular highlights.&lt;br /&gt;
|version = 1.0&lt;br /&gt;
|horde3dversion = 1.0 beta&lt;br /&gt;
|released = 2008-08-06&lt;br /&gt;
|author = [http://www.horde3d.org/forums/memberlist.php?mode=viewprofile&amp;amp;u=30 DarkAngel]|&lt;br /&gt;
}}&lt;br /&gt;
|}&lt;br /&gt;
[[category: Technique]]&lt;/div&gt;</summary>
		<author><name>Darkangel</name></author>	</entry>

	<entry>
		<id>http://horde3d.org/wiki/index.php?title=Shading_Technique_-_Gloss_Mapping&amp;diff=291</id>
		<title>Shading Technique - Gloss Mapping</title>
		<link rel="alternate" type="text/html" href="http://horde3d.org/wiki/index.php?title=Shading_Technique_-_Gloss_Mapping&amp;diff=291"/>
				<updated>2008-08-06T10:41:06Z</updated>
		
		<summary type="html">&lt;p&gt;Darkangel: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{|  border=&amp;quot;0&amp;quot; &lt;br /&gt;
| {{ContentBlock|width=800|color=white&lt;br /&gt;
|content={{!!}}&lt;br /&gt;
&lt;br /&gt;
== Overview ==&lt;br /&gt;
'''What is a gloss map?''' a texture that describes whether a surface area is [http://en.wikipedia.org/wiki/Gloss_%28material_appearance%29 matte or gloss]. This texture is used as a [http://en.wikipedia.org/wiki/Masking_%28in_art%29 mask] for specular highlights.&lt;br /&gt;
&lt;br /&gt;
'''Why might you want to use this technique?'''&amp;lt;br/&amp;gt;&lt;br /&gt;
- On materials that visibly vary in &amp;quot;shininess&amp;quot;, such as reflective metal that is partially dirty. &amp;lt;br/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Requirements:'''&amp;lt;BR/&amp;gt;&lt;br /&gt;
- RGBA texture, with the RGB channels representing color (as usual) and the alpha channel representing the gloss map&amp;lt;BR/&amp;gt;&lt;br /&gt;
- Bright areas in the gloss map will by shiny, dark areas will be matte&amp;lt;BR/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== The Technique ==&lt;br /&gt;
Seeing as specular lighting is already present in the shaders that are bundled with a new Horde3D installation, adding in a specular mask is exceedingly simple.&lt;br /&gt;
&lt;br /&gt;
Only a few minor adjustments are required, in theory all we need to do is read the alpha channel from our texture and input that data into the specular lighting equations. I will make a modified version of the parallax shader to demonstrate how to make these additions. I'll make the changes for both the deferred and forward shading versions of the code.&lt;br /&gt;
&lt;br /&gt;
The first step is the same for both the deferred and forward versions (i.e. the ATTRIBPASS and the LIGHTING contexts, respectively).&lt;br /&gt;
{{CppSourceCode|&lt;br /&gt;
description= GLSL Code to be modified in both ATTRIBPASS and LIGHTING.|&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;
//This line reads the RGB values of our texture, comment it out:&lt;br /&gt;
//vec3 albedo = texture2D( tex0, newCoords.st ).rgb;&lt;br /&gt;
//And then replace it with this code that also reads the alpha channel:&lt;br /&gt;
vec4 albedo_gloss = texture2D( tex0, newCoords.st ).rgba;&lt;br /&gt;
vec3 albedo = albedo_gloss.rgb;&lt;br /&gt;
float gloss = albedo_gloss.a;&lt;br /&gt;
&amp;lt;/source&amp;gt;}}&lt;br /&gt;
&lt;br /&gt;
This next change is for the forward shading version only.&lt;br /&gt;
{{CppSourceCode|&lt;br /&gt;
description= GLSL Code to be modified in LIGHTING.|&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;
//This line of code performs the lighting equation. The first hard-coded values of 0.3 is the specular mask value.&lt;br /&gt;
//gl_FragColor.rgb =&lt;br /&gt;
//	calcPhongSpotLight( newPos, normalize( normal ), albedo, 0.3, 16.0, -vsPos.z, 0.3 );&lt;br /&gt;
//Change the first &amp;quot;0.3&amp;quot; value to &amp;quot;gloss&amp;quot;, Like this:&lt;br /&gt;
gl_FragColor.rgb =&lt;br /&gt;
	calcPhongSpotLight( newPos, normalize( normal ), albedo, gloss, 16.0, -vsPos.z, 0.3 );&lt;br /&gt;
&amp;lt;/source&amp;gt;}}&lt;br /&gt;
&lt;br /&gt;
This next change is for the deferred shading version only.&lt;br /&gt;
{{CppSourceCode|&lt;br /&gt;
description= GLSL Code to be modified in ATTRIBPASS.|&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;
//This line of code saves the material properties. The hard-coded value of 0.3 is the specular mask value.&lt;br /&gt;
//setSpecMask( 0.3 );&lt;br /&gt;
//Change the &amp;quot;0.3&amp;quot; value to &amp;quot;gloss&amp;quot;, Like this:&lt;br /&gt;
setSpecMask( gloss );&lt;br /&gt;
&amp;lt;/source&amp;gt;}}&lt;br /&gt;
&lt;br /&gt;
== Example Result == &lt;br /&gt;
[http://horde3d.org/forums/download/file.php?id=50 Click here to view]&lt;br /&gt;
&lt;br /&gt;
== To-Do List for this Article ==&lt;br /&gt;
- Add pictures&amp;lt;BR/&amp;gt;&lt;br /&gt;
- Finish writing the descriptions ;) - this is a draft&amp;lt;BR/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
}}&lt;br /&gt;
|  valign=&amp;quot;top&amp;quot; | {{Extension_Summary&lt;br /&gt;
|name = Technique - Gloss mapping&lt;br /&gt;
|screenshot = todo.jpg&lt;br /&gt;
|description = Using an alpha channel to mask specular highlights.&lt;br /&gt;
|version = 1.0&lt;br /&gt;
|horde3dversion = 1.0 beta&lt;br /&gt;
|released = 2008-08-06&lt;br /&gt;
|author = [http://www.horde3d.org/forums/memberlist.php?mode=viewprofile&amp;amp;u=30 DarkAngel]|&lt;br /&gt;
}}&lt;br /&gt;
|}&lt;br /&gt;
[[category: Technique]]&lt;/div&gt;</summary>
		<author><name>Darkangel</name></author>	</entry>

	<entry>
		<id>http://horde3d.org/wiki/index.php?title=Shading_Technique_-_Gloss_Mapping&amp;diff=290</id>
		<title>Shading Technique - Gloss Mapping</title>
		<link rel="alternate" type="text/html" href="http://horde3d.org/wiki/index.php?title=Shading_Technique_-_Gloss_Mapping&amp;diff=290"/>
				<updated>2008-08-06T10:33:07Z</updated>
		
		<summary type="html">&lt;p&gt;Darkangel: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{|  border=&amp;quot;0&amp;quot; &lt;br /&gt;
| {{ContentBlock|width=800|color=white&lt;br /&gt;
|content={{!!}}&lt;br /&gt;
&lt;br /&gt;
'''I'm still writing this article, based on [http://www.horde3d.org/forums/viewtopic.php?f=1&amp;amp;t=446 this forum post]'''&lt;br /&gt;
&lt;br /&gt;
== Overview ==&lt;br /&gt;
'''What is a gloss map?''' a texture that describes whether a surface area is [http://en.wikipedia.org/wiki/Gloss_%28material_appearance%29 matte or gloss]. This texture is used as a [http://en.wikipedia.org/wiki/Masking_%28in_art%29 mask] for specular highlights.&lt;br /&gt;
&lt;br /&gt;
'''Why might you want to use this technique?'''&amp;lt;br/&amp;gt;&lt;br /&gt;
- On materials that visibly vary in &amp;quot;shininess&amp;quot;, such as reflective metal that is partially dirty. &amp;lt;br/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Requirements:'''&amp;lt;BR/&amp;gt;&lt;br /&gt;
- RGBA texture, with the RGB channels representing color (as usual) and the alpha channel representing the gloss map&amp;lt;BR/&amp;gt;&lt;br /&gt;
- Bright areas in the gloss map will by shiny, dark areas will be matte&amp;lt;BR/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== The Technique ==&lt;br /&gt;
Seeing as specular lighting is already present in the shaders that are bundled with a new Horde3D installation, adding in a specular mask is exceedingly simple.&lt;br /&gt;
&lt;br /&gt;
Only a few minor adjustments are required, in theory all we need to do is read the alpha channel from our texture and input that data into the specular lighting equations. I will make a modified version of the parallax shader to demonstrate how to make these additions. I'll make the changes for both the deferred and forward shading versions of the code.&lt;br /&gt;
&lt;br /&gt;
The first step is the same for both the deferred and forward versions (i.e. the ATTRIBPASS and the LIGHTING contexts, respectively).&lt;br /&gt;
{{CppSourceCode|&lt;br /&gt;
description= GLSL Code to be modified in both ATTRIBPASS and LIGHTING.|&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;
//This line reads the RGB values of our texture, comment it out:&lt;br /&gt;
//vec3 albedo = texture2D( tex0, newCoords.st ).rgb;&lt;br /&gt;
//And then replace it with this code that also reads the alpha channel:&lt;br /&gt;
vec4 albedo_gloss = texture2D( tex0, newCoords.st ).rgba;&lt;br /&gt;
vec3 albedo = albedo_gloss.rgb;&lt;br /&gt;
float gloss = albedo_gloss.a;&lt;br /&gt;
&amp;lt;/source&amp;gt;}}&lt;br /&gt;
&lt;br /&gt;
This next change is for the forward shading version only.&lt;br /&gt;
{{CppSourceCode|&lt;br /&gt;
description= GLSL Code to be modified in LIGHTING.|&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;
//This line of code performs the lighting equation. The first hard-coded values of 0.3 is the specular mask value.&lt;br /&gt;
//gl_FragColor.rgb =&lt;br /&gt;
//	calcPhongSpotLight( newPos, normalize( normal ), albedo, 0.3, 16.0, -vsPos.z, 0.3 );&lt;br /&gt;
//Change the first &amp;quot;0.3&amp;quot; value to &amp;quot;gloss&amp;quot;, Like this:&lt;br /&gt;
gl_FragColor.rgb =&lt;br /&gt;
	calcPhongSpotLight( newPos, normalize( normal ), albedo, gloss, 16.0, -vsPos.z, 0.3 );&lt;br /&gt;
&amp;lt;/source&amp;gt;}}&lt;br /&gt;
&lt;br /&gt;
This next change is for the deferred shading version only.&lt;br /&gt;
{{CppSourceCode|&lt;br /&gt;
description= GLSL Code to be modified in ATTRIBPASS.|&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;
//This line of code saves the material properties. The hard-coded value of 0.3 is the specular mask value.&lt;br /&gt;
//setSpecMask( 0.3 );&lt;br /&gt;
//Change the &amp;quot;0.3&amp;quot; value to &amp;quot;gloss&amp;quot;, Like this:&lt;br /&gt;
setSpecMask( gloss );&lt;br /&gt;
&amp;lt;/source&amp;gt;}}&lt;br /&gt;
&lt;br /&gt;
== Example Result == &lt;br /&gt;
Insert image here&lt;br /&gt;
&lt;br /&gt;
== To-Do List for this Article ==&lt;br /&gt;
- Add pictures&amp;lt;BR/&amp;gt;&lt;br /&gt;
- Finish writing the descriptions ;) - this is a draft&amp;lt;BR/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
}}&lt;br /&gt;
|  valign=&amp;quot;top&amp;quot; | {{Extension_Summary&lt;br /&gt;
|name = Technique - Gloss mapping&lt;br /&gt;
|screenshot = todo.jpg&lt;br /&gt;
|description = Using an alpha channel to mask specular highlights.&lt;br /&gt;
|version = 1.0&lt;br /&gt;
|horde3dversion = 1.0 beta&lt;br /&gt;
|released = 2008-08-06&lt;br /&gt;
|author = [http://www.horde3d.org/forums/memberlist.php?mode=viewprofile&amp;amp;u=30 DarkAngel]|&lt;br /&gt;
}}&lt;br /&gt;
|}&lt;br /&gt;
[[category: Technique]]&lt;/div&gt;</summary>
		<author><name>Darkangel</name></author>	</entry>

	<entry>
		<id>http://horde3d.org/wiki/index.php?title=Shading_Technique_-_Gloss_Mapping&amp;diff=289</id>
		<title>Shading Technique - Gloss Mapping</title>
		<link rel="alternate" type="text/html" href="http://horde3d.org/wiki/index.php?title=Shading_Technique_-_Gloss_Mapping&amp;diff=289"/>
				<updated>2008-08-06T10:20:52Z</updated>
		
		<summary type="html">&lt;p&gt;Darkangel: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{|  border=&amp;quot;0&amp;quot; &lt;br /&gt;
| {{ContentBlock|width=800|color=white&lt;br /&gt;
|content={{!!}}&lt;br /&gt;
&lt;br /&gt;
'''I'm still writing this article, based on [http://www.horde3d.org/forums/viewtopic.php?f=1&amp;amp;t=446 this forum post]'''&lt;br /&gt;
&lt;br /&gt;
== Overview ==&lt;br /&gt;
'''What is a gloss map?''' a texture that describes whether a surface area is [http://en.wikipedia.org/wiki/Gloss_%28material_appearance%29 matte or gloss]. This texture is used as a [http://en.wikipedia.org/wiki/Masking_%28in_art%29 mask] for specular highlights.&lt;br /&gt;
&lt;br /&gt;
'''Why might you want to use this technique?'''&amp;lt;br/&amp;gt;&lt;br /&gt;
- On materials that visibly vary in &amp;quot;shininess&amp;quot;, such as reflective metal that is partially dirty. &amp;lt;br/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Requirements:'''&amp;lt;BR/&amp;gt;&lt;br /&gt;
- RGBA texture, with the RGB channels representing color (as usual) and the alpha channel representing the gloss map&amp;lt;BR/&amp;gt;&lt;br /&gt;
- Bright areas in the gloss map will by shiny, dark areas will be matte&amp;lt;BR/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== The Technique ==&lt;br /&gt;
Seeing as specular lighting is already present in the shaders that are bundled with a new Horde3D installation, adding in a specular mask is exceedingly simple.&lt;br /&gt;
&lt;br /&gt;
Only a few minor adjustments are required, in theory all we need to do is read the alpha channel from our texture and input that data into the specular lighting equations. I will make a modified version of the parallax shader to demonstrate how to make these additions. I'll make the changes for both the deferred and forward shading versions of the code.&lt;br /&gt;
&lt;br /&gt;
The first step is the same for both the deferred and forward versions (i.e. the ATTRIBPASS and the LIGHTING contexts, respectively).&lt;br /&gt;
{{CppSourceCode|&lt;br /&gt;
description= GLSL Code to be modified in both ATTRIBPASS and LIGHTING.|&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;
//This line reads the RGB values of our texture, comment it out:&lt;br /&gt;
//vec3 albedo = texture2D( tex0, newCoords.st ).rgb;&lt;br /&gt;
//And then replace it with this code that also reads the alpha channel:&lt;br /&gt;
vec4 albedo_gloss = texture2D( tex0, newCoords.st ).rgba;&lt;br /&gt;
vec3 albedo = albedo_gloss.rgb;&lt;br /&gt;
float gloss = albedo_gloss.a;&lt;br /&gt;
&amp;lt;/source&amp;gt;}}&lt;br /&gt;
&lt;br /&gt;
This next change is for the forward shading version only.&lt;br /&gt;
{{CppSourceCode|&lt;br /&gt;
description= GLSL Code to be modified in LIGHTING.|&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;
//This line of code performs the lighting equation. The hard-coded values of 0.3 are the specular values.&lt;br /&gt;
//gl_FragColor.rgb =&lt;br /&gt;
//	calcPhongSpotLight( newPos, normalize( normal ), albedo, 0.3, 16.0, -vsPos.z, 0.3 );&lt;br /&gt;
//Change the &amp;quot;0.3&amp;quot; values to &amp;quot;gloss&amp;quot;, Like this:&lt;br /&gt;
gl_FragColor.rgb =&lt;br /&gt;
	calcPhongSpotLight( newPos, normalize( normal ), albedo, gloss, 16.0, -vsPos.z, gloss );&lt;br /&gt;
&amp;lt;/source&amp;gt;}}&lt;br /&gt;
&lt;br /&gt;
This next change is for the deferred shading version only.&lt;br /&gt;
{{CppSourceCode|&lt;br /&gt;
description= GLSL Code to be modified in ATTRIBPASS.|&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;
//This line of code saves the material properties. The hard-coded value of 0.3 is the specular value.&lt;br /&gt;
setSpecMask( gloss );&lt;br /&gt;
//Change the &amp;quot;0.3&amp;quot; values to &amp;quot;gloss&amp;quot;, Like this:&lt;br /&gt;
setSpecMask( 0.3 );&lt;br /&gt;
&amp;lt;/source&amp;gt;}}&lt;br /&gt;
&lt;br /&gt;
== Example Result == &lt;br /&gt;
Insert image here&lt;br /&gt;
&lt;br /&gt;
== To-Do List for this Article ==&lt;br /&gt;
- Add pictures&amp;lt;BR/&amp;gt;&lt;br /&gt;
- Finish writing the descriptions ;) - this is a draft&amp;lt;BR/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
}}&lt;br /&gt;
|  valign=&amp;quot;top&amp;quot; | {{Extension_Summary&lt;br /&gt;
|name = Technique - Gloss mapping&lt;br /&gt;
|screenshot = todo.jpg&lt;br /&gt;
|description = Using an alpha channel to mask specular highlights.&lt;br /&gt;
|version = 1.0&lt;br /&gt;
|horde3dversion = 1.0 beta&lt;br /&gt;
|released = 2008-08-06&lt;br /&gt;
|author = [http://www.horde3d.org/forums/memberlist.php?mode=viewprofile&amp;amp;u=30 DarkAngel]|&lt;br /&gt;
}}&lt;br /&gt;
|}&lt;br /&gt;
[[category: Technique]]&lt;/div&gt;</summary>
		<author><name>Darkangel</name></author>	</entry>

	<entry>
		<id>http://horde3d.org/wiki/index.php?title=Shading_Technique_-_Gloss_Mapping&amp;diff=288</id>
		<title>Shading Technique - Gloss Mapping</title>
		<link rel="alternate" type="text/html" href="http://horde3d.org/wiki/index.php?title=Shading_Technique_-_Gloss_Mapping&amp;diff=288"/>
				<updated>2008-08-06T04:15:43Z</updated>
		
		<summary type="html">&lt;p&gt;Darkangel: Draft layout&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{|  border=&amp;quot;0&amp;quot; &lt;br /&gt;
| {{ContentBlock|width=800|color=white&lt;br /&gt;
|content={{!!}}&lt;br /&gt;
&lt;br /&gt;
'''I'm still writing this article, based on [http://www.horde3d.org/forums/viewtopic.php?f=1&amp;amp;t=446 this forum post]'''&lt;br /&gt;
&lt;br /&gt;
== Overview ==&lt;br /&gt;
'''Defining a gloss map:''' a texture that describes whether a surface area is [http://en.wikipedia.org/wiki/Gloss_%28material_appearance%29 matte or gloss]. This texture is used as a [http://en.wikipedia.org/wiki/Masking_%28in_art%29 mask] for specular highlights.&lt;br /&gt;
&lt;br /&gt;
'''Why might you want to use this technique?'''&amp;lt;br/&amp;gt;&lt;br /&gt;
- On materials that visibly vary in &amp;quot;shininess&amp;quot;, such as reflective metal that is partially dirty. &amp;lt;br/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Requirements:'''&amp;lt;BR/&amp;gt;&lt;br /&gt;
- RGBA Color Map, with the alpha channel representing the gloss map&amp;lt;BR/&amp;gt;&lt;br /&gt;
- Bright areas in the gloss map will by shiny, dark areas will be matte&amp;lt;BR/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== The Technique ==&lt;br /&gt;
Seeing as specular lighting is already present in the shaders that are bundled with a new Horde3D installation, adding in a specular mask is exceedingly simple.&lt;br /&gt;
In theory this is all we need:&lt;br /&gt;
{{CppSourceCode|&lt;br /&gt;
description= GLSL Code|&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;
todo&lt;br /&gt;
&amp;lt;/source&amp;gt;}}&lt;br /&gt;
&lt;br /&gt;
''Description of what's going on in the above code''&lt;br /&gt;
&lt;br /&gt;
Here is an example of Horde3D's original parallax shader, with the above modifications applied:&lt;br /&gt;
{{CppSourceCode|&lt;br /&gt;
description= Full GLSL Fragment Shader |&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;
Todo&amp;lt;/source&amp;gt;}}&lt;br /&gt;
&lt;br /&gt;
== Example Result == &lt;br /&gt;
Insert image here&lt;br /&gt;
&lt;br /&gt;
== To-Do List for this Article ==&lt;br /&gt;
- Add pictures&amp;lt;BR/&amp;gt;&lt;br /&gt;
- Finish writing the descriptions ;) - this is a draft&amp;lt;BR/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
}}&lt;br /&gt;
|  valign=&amp;quot;top&amp;quot; | {{Extension_Summary&lt;br /&gt;
|name = Technique - Gloss mapping&lt;br /&gt;
|screenshot = todo.jpg&lt;br /&gt;
|description = Using an alpha channel to mask specular highlights.&lt;br /&gt;
|version = 1.0&lt;br /&gt;
|horde3dversion = 1.0 beta&lt;br /&gt;
|released = 2008-08-06&lt;br /&gt;
|author = [http://www.horde3d.org/forums/memberlist.php?mode=viewprofile&amp;amp;u=30 DarkAngel]|&lt;br /&gt;
}}&lt;br /&gt;
|}&lt;br /&gt;
[[category: Technique]]&lt;/div&gt;</summary>
		<author><name>Darkangel</name></author>	</entry>

	<entry>
		<id>http://horde3d.org/wiki/index.php?title=Horde3D_Wiki:Community_portal&amp;diff=287</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=287"/>
				<updated>2008-08-06T02:17:09Z</updated>
		
		<summary type="html">&lt;p&gt;Darkangel: Glow and Gloss mapping links&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;__NOEDITSECTION__{{ContentBlock|width=800|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|width=800&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;
==How-To setup a Horde3D 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;
==Tutorials==&lt;br /&gt;
[[Category: Tutorials]]&lt;br /&gt;
&lt;br /&gt;
Fell free to write your tutorials here, for the benefit of the whole community. &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;
===Intermediate===&lt;br /&gt;
&lt;br /&gt;
===Advanced===&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;
&lt;br /&gt;
==Content Import==&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 - Modo]] - Exporting from Modo. &lt;br /&gt;
#[[Collada - Blender]] - Exporting from Blender.&lt;br /&gt;
}}&lt;/div&gt;</summary>
		<author><name>Darkangel</name></author>	</entry>

	<entry>
		<id>http://horde3d.org/wiki/index.php?title=User_talk:Darkangel&amp;diff=3</id>
		<title>User talk:Darkangel</title>
		<link rel="alternate" type="text/html" href="http://horde3d.org/wiki/index.php?title=User_talk:Darkangel&amp;diff=3"/>
				<updated>2008-04-09T01:09:57Z</updated>
		
		<summary type="html">&lt;p&gt;Darkangel: New page: Just testing...  Congrat's on the new forum and wiki Nicolas!&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Just testing...&lt;br /&gt;
&lt;br /&gt;
Congrat's on the new forum and wiki Nicolas!&lt;/div&gt;</summary>
		<author><name>Darkangel</name></author>	</entry>

	</feed>