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

	<entry>
		<id>http://horde3d.org/wiki/index.php?title=Code_Snippets&amp;diff=687</id>
		<title>Code Snippets</title>
		<link rel="alternate" type="text/html" href="http://horde3d.org/wiki/index.php?title=Code_Snippets&amp;diff=687"/>
				<updated>2010-10-18T19:55:04Z</updated>
		
		<summary type="html">&lt;p&gt;Orm: Added example to help with custom OpenGL.&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;
===Using Custom GL Code After Horde3D===&lt;br /&gt;
Horde3D has a bad habbit of messing with the OpenGL states after it is finished, so it is necessary with a few third party libraries to make sure that the OpenGL state is at its default settings before rendering. Here is an example using CEGUI. It is assumed you can logically piece together what the main loop would look like.&lt;br /&gt;
&lt;br /&gt;
{{CppSourceCode| &lt;br /&gt;
description = Custom OpenGL after Horde3D.|&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 Engine::InitializeRenderer()&lt;br /&gt;
{&lt;br /&gt;
    glPushAttrib(GL_ALL_ATTRIB_BITS); // save default attributes&lt;br /&gt;
&lt;br /&gt;
    LOG(&amp;quot;Initializing rendering engine...&amp;quot;,INFO);&lt;br /&gt;
    if(!h3dInit())&lt;br /&gt;
    {&lt;br /&gt;
        LOG(&amp;quot;Error initializing Horde3D. Aborting.&amp;quot;,FATAL);&lt;br /&gt;
        Kill();&lt;br /&gt;
    }&lt;br /&gt;
    LOG(&amp;quot;Running the game.&amp;quot;,INFO);&lt;br /&gt;
&lt;br /&gt;
    glClearDepth(1.f);&lt;br /&gt;
    glClearColor(0.f, 0.f, 0.5f, 0.f);&lt;br /&gt;
    glEnable(GL_DEPTH_TEST);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void Engine::FinalizeRenderer()&lt;br /&gt;
{&lt;br /&gt;
    if(stage)&lt;br /&gt;
    {&lt;br /&gt;
        h3dRender(active_camera);&lt;br /&gt;
    }&lt;br /&gt;
    h3dFinalizeFrame();&lt;br /&gt;
    // attributes here are now messed up&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void Engine::FinalizeGUI()&lt;br /&gt;
{&lt;br /&gt;
    glPopAttrib(); // pop back to default state since horde3d messed with the states.&lt;br /&gt;
&lt;br /&gt;
    CEGUI::System::getSingleton().renderGUI();&lt;br /&gt;
&lt;br /&gt;
    glPushAttrib(GL_ALL_ATTRIB_BITS); // save the default state again before going back to Horde3D&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;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>Orm</name></author>	</entry>

	</feed>