budnhead/org.nhengine/graphics/ShaderProgram.cs

206 lines
4.5 KiB
C#

using System;
using System.IO;
using OpenTK.Graphics.OpenGL;
using OpenTK;
/**
* ShaderProgram Class
*
* Defines a shading program to use for drawing operations
*
* The coordinate space used to describe the world is called "WorldSpace"
*
* Each object to be drawn/used in the "World" is based on its individual coordinate space "ObjectSpace"
* Each object provides a Transformation Matrix "mObject" which translates ObjectSpace to WorldSpace.
*
* WorldSpace = mObject * ObjectSpace
*
* To render the scene another coordinate space is used, which is called "CameraSpace"
* The transformation matrix used to translate from WorldSpace to CameraSpace is called "mCamera"
*
*
*
*
*
* As convention the following data will be given to shaders:
*
* Uniform:
*
* mTranslation World Coordinate Translation
* mRotation Rotation to camera view direction
* mWorld Transformation Matrix to world coordinate system
*
* mDistance Camera Distance translation (Z)
* mCamera Transformation to camera space
* mProjection Projection Matrix
*
* mComplete Result of all Matrices
*
* Stream Data:
*
* iv_position Vertex coordinate
* iv_color Vertex Color
* iv_normal Vertex normal
* iv_uv Vertex texture coordinate
*
*
**/
namespace org.nhengine.graphics
{
public class ShaderProgram
{
Shader vertexShader;
Shader fragmentShader;
int id;
int nm_Translation,
nm_Rotation,
nm_World,
nm_Distance,
nm_Camera,
nm_Projection,
nm_Complete;
public ShaderProgram(Shader vertexShader, Shader fragmentShader)
{
init(vertexShader, fragmentShader);
}
public ShaderProgram(String vertexShader, String fragmentShader)
{
init(
new Shader(ShaderType.VertexShader, vertexShader),
new Shader(ShaderType.FragmentShader, fragmentShader)
);
}
public ShaderProgram(Stream vertexShader, Stream fragmentShader)
{
init(
new Shader(ShaderType.VertexShader, new StreamReader(vertexShader).ReadToEnd()),
new Shader(ShaderType.FragmentShader, new StreamReader(fragmentShader).ReadToEnd())
);
}
private void init(Shader vertexShader, Shader fragmentShader){
this.vertexShader = vertexShader;
this.fragmentShader = fragmentShader;
this.id = GL.CreateProgram();
GL.AttachShader(this.id, this.vertexShader.ID);
GL.AttachShader(this.id, this.fragmentShader.ID);
GL.BindAttribLocation(this.id, 0, "iv_position");
GL.BindAttribLocation(this.id, 1, "iv_color");
GL.BindAttribLocation(this.id, 2, "iv_normal");
GL.BindAttribLocation(this.id, 3, "iv_uv");
GL.LinkProgram(this.id);
Console.WriteLine("Shader Program Result: {0}", GL.GetProgramInfoLog(this.id));
nm_Translation = GL.GetUniformLocation(this.ID, "mTranslation");
nm_Rotation = GL.GetUniformLocation(this.ID, "mRotation");
nm_World = GL.GetUniformLocation(this.ID, "mWorld");
nm_Distance = GL.GetUniformLocation(this.ID, "mDistance");
nm_Camera = GL.GetUniformLocation(this.ID, "mCamera");
nm_Projection = GL.GetUniformLocation(this.ID, "mProjection");
nm_Complete = GL.GetUniformLocation(this.ID, "mComplete");
}
public int ID
{
get { return this.id; }
}
public int nmTranslation
{
get
{
return nm_Translation;
}
}
public int nmRotation
{
get
{
return nm_Rotation;
}
}
public int nmWorld
{
get
{
return nm_World;
}
}
public int nmDistance
{
get
{
return nm_Distance;
}
}
public int nmCamera
{
get
{
return nm_Camera;
}
}
public int nmProjection
{
get
{
return nm_Projection;
}
}
public int nmComplete
{
get { return this.nm_Complete; }
}
public void use(GLCamera camera){
GL.UseProgram(this.id);
Matrix4
mTranslate,
mRotation,
mWorld,
mDistance,
mCamera,
mProjection,
mComplete;
mTranslate = camera.MTranslation;
mRotation = camera.MRotation;
mWorld = mTranslate * mRotation;
mDistance = camera.MDistance;
mCamera = mWorld * mDistance;
mProjection = camera.MProjection;
mComplete = mCamera * mProjection;
GL.UniformMatrix4(nm_Translation, false, ref mTranslate);
GL.UniformMatrix4(nm_Rotation, false, ref mRotation);
GL.UniformMatrix4(nm_World, false, ref mWorld);
GL.UniformMatrix4(nm_Distance, false, ref mDistance);
GL.UniformMatrix4(nm_Camera, false, ref mCamera);
GL.UniformMatrix4(nm_Projection, false, ref mProjection);
GL.UniformMatrix4(nm_Complete, false, ref mComplete);
}
}
}