206 lines
4.5 KiB
C#
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);
|
|
|
|
}
|
|
}
|
|
}
|