This project is read-only.

Koeky 3D and Shaders

This tutorial will explain how to use shaders in the Koeky 3D framework. I have written this framework not to use any of the old fixed function OpenGL. Therefore it is required that you use shaders.

Shaders are wrapped inside the Technique class in Koeky 3D. The technique class has 3 tasks:
  • Loading a shader
  • Defining vertex attributes for the shader
  • Linking the shader

Optionally it can also retrieve the uniform location of shader variables. The uniforms projection matrix, view matrix and world matrix are already implemented by every Technique by default.

As an example I will explain how to create a default technique which will allow the drawing of objects with or without a texture. When no texture is defined a constant color is used to shade the object.

First off: every technique you write extends the Technique class and must implement two methods. These are:
  • public bool Initialise()
  • public void Enable()

The first method will perform the three tasks explained earlier. The second method is called when the Technique is enabled and can be used to set some variables (if needed).

We will call our render technique DefaultTechnique. The code is:
public class DefaultTechnique : Technique
{
    private int useTextureLocation, drawColorLocation;

    // Initialises the technique
    // If false is returned it means something went wrong.
    // You can use base.ErrorMessage to see the error message.
    public override bool Initialise()
    {
        // Load the shader. The third parameter is the geometry shader.
        // By leaving either of the three fields empty they are ignored.
        // You can also use the method CreateShaderFromFile to load a shader
        // from disk.
        if (!base.CreateShaderFromSource(Resources.DefaultVertexShader,   
            Resources.DefaultFragmentShader, ""))
                 return false;

        // Set shader attributes
        base.SetShaderAttribute((int)BufferAttribute.Vertex, "in_Vertex");
        base.SetShaderAttribute((int)BufferAttribute.TexCoord, "in_TexCoord");
        base.SetShaderAttribute((int)BufferAttribute.Normal, "in_Normal");

        // Link the shader
        if (!base.Finalize())
            return false;

        // Retrieve some uniform locations
        this.useTextureLocation = base.GetUniformLocation("useTexture");
        this.drawColorLocation = base.GetUniformLocation("drawColor");

        // Validate the shader
        if(!base.Validate())
            return false;

        return true;
    }

    public override void Enable()
    {
            // Nothing to do here
    }

    // Set the use of a texture in the shader to true or false
    public bool UseTexture
    {
        set
        {
            base.shader.SetVariable(this.useTextureLocation, value);
        }
    }
    // Set the color to use when no texture is used in the shader
    public Color4 DrawColor
    {
        set
        {
            base.shader.SetVariable(this.drawColorLocation, value);
        }
    }
}


This wraps the entire shader nicely away from the user. And by using properties settings shader uniforms is easy.

Ofcourse this class will be useless if we do not have a shader. The vertex shader looks like this:
#version 140
in vec3 in_Vertex;
in vec2 in_TexCoord;

out vec2 out_TexCoord;

uniform mat4x4 projection, view, world;

void main()
{
	out_TexCoord = in_TexCoord;

	gl_Position = projection * view * world * vec4(in_Vertex, 1.0f);
}

The fragment shader looks like this:
#version 140
in vec2 out_TexCoord;

uniform sampler2D texture;
uniform int useTexture;
uniform vec4 drawColor;

void main()
{
	if(useTexture == 1)
		gl_FragColor = texture2D(texture, out_TexCoord);
	else
		gl_FragColor = drawColor;
}


As you can see the naming of the variables in the shader and the DefaultTechnique class match. This is, ofcourse, required if you want your system to work correctly.

That's it. By using the Technique class you can easily load shaders, define vertex attributes and retrieve/set uniforms!

Last edited Aug 13, 2012 at 3:21 PM by Mathyn, version 6

Comments

No comments yet.