-
Notifications
You must be signed in to change notification settings - Fork 2
Lesson 07
We will need the switching of shaders for our final structure lesson and since we wanted to switch from ShaderPrograms to the more powerful ShaderEffects anyway, we'll do the transition to ShaderEffects now and Targets in the next Lesson.
Flexibility is important if you are working with shaders, so we want at least some of the basic shaders covered: a diffuse color shader, a diffuse texture shader, a toon color shader and a toon texture shader.
First about the ShaderEffects themself. A ShaderEffect takes 2 parameters, first an array of EffectPassDeclaration and another array of EffectParameterDeclaration. Each EffectPassDeclaraion elemet in the array is a seperate render pass and contains the shader code (vertex- and pixelshader) and a set of render states. Each EffectParameterDeclaration element makes an 'uniform' shader variable accessible.
The shader code itself is plain OpenGL shading language, but keep in mind that if you want your application working in a browser you have to restrict yourself to the OpenGL ES subset.
So, remove everything about ShaderProgram and IShaderParam as well as the SetColor()
methodes. We are now also working with up up to two textures in addition to a color, so that part in our varaibale definition in GameEntity should look similar to the following.
private ShaderEffect _shaderEffect;
private ITexture _iTexture1;
private ITexture _iTexture2;
private float4 _color = new float4(0.5f, 0.5f, 0.5f, 1);
For our 4 ShaderEffects we have 4 methods in Shader.cs, lets mirror that for our GameEntities:
public void SetShader(float4 color)
{
_color = color;
_shaderEffect = Shader.GetShaderEffect(_rc, _color);
}
public void SetShader(String texturePath)
{
var imgData = _rc.LoadImage(texturePath);
_iTexture1 = _rc.CreateTexture(imgData);
_shaderEffect = Shader.GetShaderEffect(_rc, _iTexture1);
}
These are 2 of the 4, in the second one we are working with textures the first time so let me explain. First we are loading the image data from the filesystem, but this is not yet usable by shaders, we have to convert is to an ITexture in order for shaders to use it, that's it. The other 2 methods are just handling a texture and a color, and handeling two textures.
You might have noticed we are passing the RenderContext over to the ShaderEffects, and if you follow it into Shader.cs you find a line shaderEffect.AttachToContext(rc);
. So each ShaderEffect knows the RenderContext it renders to. With ShaderPrograms you remember we hat to prepare the rendering, by setting it, setting the ShaderParams and then telling RC to render the mesh. ShaderEffects bring the convenience of doing all of this for you, so our Render()
method in GameEntity boils down to just this:
public void Render(float4x4 camMatrix)
{
_rc.ModelView = CorrectionMatrix * Position * camMatrix;
_shaderEffect.RenderMesh(_mesh);
}
Now we still got errors in our GameWorld, these are easy to fix: just replace SetColor()
with a SetShader()
of your liking and you are done. It should look something like this now:
_furniture.Add(new GameEntity("Assets/cube.obj.model", _rc, -100, 0, -500));
_furniture[0].SetShader(new float4(1, 0, 0, 1));
_furniture[0].SetCorrectionMatrix(float4x4.Scale(0.5f));
_furniture.Add(new GameEntity("Assets/cube.obj.model", _rc, 100, 0, -500, (float) Math.PI/4, (float) Math.PI/4));
_furniture[1].SetShader(new float4(0, 1, 0, 1), "Assets/toon_generic_5_tex.png", new float4(0, 0, 0, 1), new float2(10, 10));
[> Lesson 08 - Structure: Target](Lesson 08)