Basic Pipeline Tutorial

From Horde3D Wiki
Jump to: navigation, search

Overview

In this tutorial, I will try to show you how the Horde3D pipeline system works. At the first look, when you haven't really worked with an advanced pipeline system before, it may look a little bit complicated, but I will show how user friendly it is and how this powerful tool is useful.

Requirements:
- The Horde3D SDK 1.0.0 Beta2

Creating the pipeline

First of all, I will show you how to create a really basic pipeline with only one context. For this, we will use the chicago example in the Horde3D SDK to see how the pipeline and his context can affect a scene. If you use Visual Studio, open the "Horde3D.sln" file to get into the chicago sample, otherwhise use your configuration to open the chicago example or edit each files in your favorite editor. In the "app.cpp" file, we will change the foward pipeline resource to take our custom pipeline instead of the forward pipeline, so in the Application::init() function change this line:

Old code
_forwardPipeRes = Horde3D::addResource( ResourceTypes::Pipeline, "forward.pipeline.xml", 0 );



to this line:

New code code
_forwardPipeRes = Horde3D::addResource( ResourceTypes::Pipeline, "myPipeline.pipeline.xml", 0 );



Now, we need to create the "myPipeline.pipeline.xml" file. Go in the "Horde3D\Binaries\Content\pipelines" folder, and create a file named "myPipeline.pipeline.xml" . Open this file and add this :

myPipeline.pipeline.xml
<Pipeline>
	<CommandQueue>
	
		<Stage id="FirstStage" link="globalSettings.material.xml">
			<SwitchTarget target="" />
			<ClearTarget depthBuf="true" colBuf0="true" />
			
			<DrawGeometry context="AMBIENTCOLOR" class="" />

		</Stage>
		
	</CommandQueue>
</Pipeline>



I have tried to make this pipeline as simple as possible. I will explain how it works :

Pipeline tag
<Pipeline>
</Pipeline>

This tag means that its child tags are going to be related to pipeline tags.



CommandQueuetag tag
<CommandQueue>	
</CommandQueue>


This tag means that its child tags are going to be related to direct rendering tags.



Stage tag
<Stage id="FirstStage" link="globalSettings.material.xml">
</Stage>

The stage is here to include a series of actions, and you can have multiple stages if you want, even if in this example we have only one. It is useful since you can disable or enable a stage within an Horde3D function, and you can link it a material within the optional "link" attribute. If you want, you can look at the "globalSettings.material.xml" file to see what it contains, and if everyting is normal, you should see that a cube map is binded to the texture unit 7, this gonna be the ambient texture that will determine the ambient color of the scene. Finally, for each stages, don't forget to add an id, and in this example the id gonna be "FirstStage".



SwitchTarget tag
<SwitchTarget target="" />

This tag is useful to designate a render target. It can be a buffer, but in this example we don't have any buffers so the target is the screen. An empty "target" means that everyhing next, until a new "SwitchTarget" tag, gonna be rendered on the screen. When you use a buffer as a target, it is not rendered on the screen, so an empty "target" attribute is required somewhere for each pipelines.



ClearTarget tag
<ClearTarget depthBuf="true" colBuf0="true" />

This tag is used to clear the content of the current target. The attribute "depthBuf" is used to determine if you want to clear the depth buffer of the target, and each "colBufX" is an attribute to clear the specified color buffer of the target. In this example, we use only one color buffer.



DrawGeometry tag
<DrawGeometry context="AMBIENTCOLOR" class="" />

This tag mean that you want to draw geometries in the current target. The "context" attribute designate the shader used to render the geometry. It is directly linked to the .shader.xml of each materials of each geometries. If a geometry linked to a material don't have this context in his shader file, the geometry won't be rendered. The class attribute linked to the material file, and an empty "class" attribute means that each class will be used.



Now you have to compile the chicago example. Go in the "build" folder, and copy the new executable in the "win32" folder of the SDK. If you execute this example you should see nothing. If you look at the engine log and there is no error, it means that everyhing have been rightly done. If you see a black screen, it's because there is no "AMBIENTCOLOR" in each shader linked to each geometry. You have to add this context to each used shaders.

In the chicago sample, three shaders are used : one for the animated model one for the sky and one for the platform. Open the "skinning.shader.xml" file since it's the shader used for the animated man. Next, you have to add this within the "shader" tag:

Shader
	<Context id="AMBIENTCOLOR">
		<VertexShader>
			<InsCode code="utilityLib/vertCommon.glsl" />
			<DefCode>
			<![CDATA[
				// Those attributes are given by the Horde3D context
				attribute vec2 texCoords0; 	// Tex coordinate
				attribute vec3 normal;		// The normal vector of the vertex

				varying vec2 vTextCoords;	// Tex coordinate
				varying vec3 vNormal;		// The normal in world space

				void main( void )
				{
				
					// Get the world position of the vertex. At his initial position, gl_Vertex is in object space,
					// so we must transform his initial position to get the world position
					vec4 pos = calcWorldPos( gl_Vertex );
					
					// Get the normal in the world space from the object space
					vNormal = calcWorldVec( normal );
					
					// Get the tex coordinate
					vTextCoords = texCoords0;
					
					// The gl_ModelViewProjectionMatrix contain two matrices. The first one is the modelview matrix, and 
					// within the horde3d context, this matrix transform a position into the view space, or camera space.
					// To get the view space position with this matrix, you must first get the world position of the vertex before.
					// The second matrix is the projection matrix, it is used to project the image into clipping space.
					gl_Position = gl_ModelViewProjectionMatrix * pos;
				}
			]]>
			</DefCode>
		</VertexShader>
		
		<FragmentShader>
			<DefCode>
			<![CDATA[
				uniform sampler2D tex0;		// This is the first texture, it is defined within the material file of the man
				uniform samplerCube tex7;	// This texture is from the global setting material that we have linked in the pipeline file
				varying vec3 vNormal;		// The normal in world space
				varying vec2 vTextCoords;	// The tex coordinate

				void main( void )
				{
					// Get the texture color of the current texel
					vec3 albedo = texture2D( tex0, vTextCoords ).rgb;
					
					// Get the ambient color of the texel within the ambient cubemap defined in the "globalSettings.material.xml" file.
					vec3 ambient = textureCube( tex7, vNormal ).rgb;
					
					// Get the final texel color by mixing the ambient and the albedo color
					gl_FragColor.rgb = albedo * ambient;
				}
			]]>
			</DefCode>
		</FragmentShader>
	</Context>



As you can see, the id of the context tag is "AMBIENTCOLOR", exactly like the context in our pipeline. It means that within this context this shader will be executed for the current geometry. Then, you have the "InsCode" tag. It is here to insert the "vertCommon.glsl" file wich contain some really useful functions for the vertex shader, like "calcWorldVec()" and "calcWorldPos()". Finally, I have tried to make the vertex and the pixel shader self-explained, so you can read them if you want to learn how basically the context for the shader is within Horde3D.

Now you can execute the chicago sample and you should see each man moving, but they sould not have any animations because, in the shader, we don't use skinning. If you want to learn how skining work with Horde3D, look at the shader within the "AMBIENT" context of the file, and you should see the difference between both vertex shaders. For the other two shaders, the one for the sly and the one for the platform, you can copy the "AMBIENT" context of each shaders file and name them "AMBIENTCOLOR" to see them in the scene.


Conclusion

Finally, I have tried to make this tutorial as simple as possible, with a basic pipeline, so that it shouldn't be too hard for any programmers to learn how the pipeline system work. It's why there is no lighting or multiple buffers, but with the basics, you can learn more by yourself by looking at any of the others Horde3D SDK pipelines and by trying things by yourself!

Tutorial - Basic Pipeline Tutoial
[[Image:]]
A basic pipeline tutorial
Version: 1.0
Compatible with Horde3D: 1.0 beta 2
Release date: 2009-01-04
Author(s): Mikmacer