static string GetVertSource (MeshShaderSettings settings) { var sb = new StringBuilder(); sb.Append("#version ").AppendLine(ShaderVersion); AppendDefines(sb, settings); AppendUniform(sb, settings); AppendAttribute(sb, settings); AppendVarying(sb, settings, true); sb.AppendLine("void main() {"); sb.AppendLine(" vec4 p = Position;"); if (settings.BoneSlotCount > 0) { sb.AppendLine(" p = ("); for (var i = 0; i < settings.BoneSlotCount; i++) { sb.Append(" BoneWeight").Append(i).Append(" * Bones[int(BoneIndex").Append(i).Append(")]"); sb.AppendLine(i == settings.BoneSlotCount - 1 ? ") * p;" : " + "); } } sb.AppendLine(" normal = normalize((NormalMatrix * Normal).xyz);"); sb.AppendLine(" v = (WorldView * p).xyz;"); for (var i = 0; i < 4; i++) sb.Append(" texCoord").Append(i).Append(" = TexCoord").Append(i).AppendLine(";"); sb.AppendLine(" gl_Position = WorldViewProjection * p;"); sb.AppendLine("}"); Console.WriteLine(sb.ToString()); return sb.ToString(); }
static string GetFragSource (MeshShaderSettings settings) { var sb = new StringBuilder(); sb.Append("#version ").AppendLine(ShaderVersion); AppendDefines(sb, settings); AppendUniform(sb, settings); AppendVarying(sb, settings, false); sb.AppendLine("void main() {"); sb.AppendLine(" vec3 n = normal;"); sb.AppendLine(" vec4 a = ColorAmbient;"); sb.AppendLine(" vec4 d = ColorDiffuse;"); sb.AppendLine(" vec4 s = ColorSpecular;"); sb.AppendLine(" vec4 e = ColorEmissive;"); sb.AppendLine(" vec4 tmp;"); if (settings.Diffuse != null) { for (var i = 0; i < settings.Diffuse.Length; i++) sb.AppendFormat(FragDiffuse, i); } if (settings.Normal != null) { for (var i = 0; i < settings.Normal.Length; i++) sb.AppendFormat(FragNormal, i); } if (settings.Specular != null) { for (var i = 0; i < settings.Specular.Length; i++) sb.AppendFormat(FragSpecular, i); } if (settings.Emissive != null) { for (var i = 0; i < settings.Emissive.Length; i++) sb.AppendFormat(FragEmissive, i); } sb.AppendLine(FragPhong); sb.AppendLine("}"); return sb.ToString(); }
static string GetVertSource(MeshShaderSettings settings) { var sb = new StringBuilder(); sb.Append("#version ").AppendLine(ShaderVersion); AppendDefines(sb, settings); AppendUniform(sb, settings); AppendAttribute(sb, settings); AppendVarying(sb, settings, true); sb.AppendLine("void main() {"); sb.AppendLine(" vec4 p = Position;"); if (settings.BoneSlotCount > 0) { sb.AppendLine(" p = ("); for (var i = 0; i < settings.BoneSlotCount; i++) { sb.Append(" BoneWeight").Append(i).Append(" * Bones[int(BoneIndex").Append(i).Append(")]"); sb.AppendLine(i == settings.BoneSlotCount - 1 ? ") * p;" : " + "); } } sb.AppendLine(" normal = normalize((NormalMatrix * Normal).xyz);"); sb.AppendLine(" v = (WorldView * p).xyz;"); for (var i = 0; i < 4; i++) { sb.Append(" texCoord").Append(i).Append(" = TexCoord").Append(i).AppendLine(";"); } sb.AppendLine(" gl_Position = WorldViewProjection * p;"); sb.AppendLine("}"); return(sb.ToString()); }
static void AppendVarying(StringBuilder sb, MeshShaderSettings settings, bool output) { sb.AppendLine("varying vec3 normal;"); sb.AppendLine("varying vec3 v;"); for (var i = 0; i < 4; i++) { sb.Append("varying").Append(" vec2 texCoord").Append(i).AppendLine(";"); } }
static void AppendUniform(StringBuilder sb, MeshShaderSettings settings) { sb.AppendLine("uniform mat4 WorldViewProjection;"); sb.AppendLine("uniform mat4 WorldView;"); sb.AppendLine("uniform mat4 NormalMatrix;"); sb.AppendLine("uniform vec4 ColorAmbient;"); sb.AppendLine("uniform vec4 ColorDiffuse;"); sb.AppendLine("uniform vec4 ColorSpecular;"); sb.AppendLine("uniform vec4 ColorEmissive;"); sb.AppendLine("uniform float Shininess;"); sb.AppendLine("uniform float ShininessStrength;"); if (settings.Diffuse != null) { for (var i = 0; i < settings.Diffuse.Length; i++) { sb.Append("uniform sampler2D DiffuseMap").Append(i.ToString()).AppendLine(";"); } } if (settings.Normal != null) { for (var i = 0; i < settings.Normal.Length; i++) { sb.Append("uniform sampler2D NormalMap").Append(i.ToString()).AppendLine(";"); } } if (settings.Specular != null) { for (var i = 0; i < settings.Specular.Length; i++) { sb.Append("uniform sampler2D SpecularMap").Append(i.ToString()).AppendLine(";"); } } if (settings.Emissive != null) { for (var i = 0; i < settings.Emissive.Length; i++) { sb.Append("uniform sampler2D EmissiveMap").Append(i.ToString()).AppendLine(";"); } } if (settings.BoneCount > 0) { sb.Append("uniform mat4 Bones[").Append(settings.BoneCount).AppendLine("];"); } sb.AppendLine("uniform int NumLights;"); if (settings.MaxLights > 0) { sb.AppendLine("uniform int LightType[MAX_NUM_LIGHTS];"); sb.AppendLine("uniform vec3 LightVector[MAX_NUM_LIGHTS];"); sb.AppendLine("uniform vec3 LightAmbient[MAX_NUM_LIGHTS];"); sb.AppendLine("uniform vec3 LightDiffuse[MAX_NUM_LIGHTS];"); sb.AppendLine("uniform vec3 LightSpecular[MAX_NUM_LIGHTS];"); sb.AppendLine("uniform vec3 LightAttenuation[MAX_NUM_LIGHTS];"); } }
static void AppendAttribute(StringBuilder sb, MeshShaderSettings settings) { sb.AppendLine("attribute vec4 Position;"); sb.AppendLine("attribute vec4 Normal;"); for (var i = 0; i < 4; i++) { sb.Append("attribute vec2 TexCoord").Append(i).AppendLine(";"); } for (var i = 0; i < settings.BoneSlotCount; i++) { sb.Append("attribute float BoneWeight").Append(i).AppendLine(";"); sb.Append("attribute float BoneIndex").Append(i).AppendLine(";"); } }
static string GetFragSource(MeshShaderSettings settings) { var sb = new StringBuilder(); sb.Append("#version ").AppendLine(ShaderVersion); AppendDefines(sb, settings); AppendUniform(sb, settings); AppendVarying(sb, settings, false); sb.AppendLine("void main() {"); sb.AppendLine(" vec3 n = normal;"); sb.AppendLine(" vec4 a = ColorAmbient;"); sb.AppendLine(" vec4 d = ColorDiffuse;"); sb.AppendLine(" vec4 s = ColorSpecular;"); sb.AppendLine(" vec4 e = ColorEmissive;"); sb.AppendLine(" vec4 tmp;"); if (settings.Diffuse != null) { for (var i = 0; i < settings.Diffuse.Length; i++) { sb.AppendFormat(FragDiffuse, i); } } if (settings.Normal != null) { for (var i = 0; i < settings.Normal.Length; i++) { sb.AppendFormat(FragNormal, i); } } if (settings.Specular != null) { for (var i = 0; i < settings.Specular.Length; i++) { sb.AppendFormat(FragSpecular, i); } } if (settings.Emissive != null) { for (var i = 0; i < settings.Emissive.Length; i++) { sb.AppendFormat(FragEmissive, i); } } sb.AppendLine(FragPhong); sb.AppendLine("}"); return(sb.ToString()); }
static void AppendDefines(StringBuilder sb, MeshShaderSettings settings) { sb.Append("#define MAX_NUM_LIGHTS ").AppendLine(settings.MaxLights.ToString()); if (settings.Diffuse != null) { for (var i = 0; i < settings.Diffuse.Length; i++) { var item = settings.Diffuse[0]; sb.Append("#define DIFFUSE_INDEX").Append(i.ToString()).Append(" texCoord").AppendLine(item.Index.ToString()); sb.Append("#define DIFFUSE_BLEND").Append(i.ToString()).Append(" ").AppendLine(item.BlendFactor.ToString()); sb.Append("#define DIFFUSE_OP").Append(i.ToString()).Append(" ").AppendLine(((int)item.Operation).ToString()); } } if (settings.Normal != null) { for (var i = 0; i < settings.Normal.Length; i++) { var item = settings.Normal[0]; sb.Append("#define NORMAL_INDEX").Append(i.ToString()).Append(" texCoord").AppendLine(item.Index.ToString()); sb.Append("#define NORMAL_BLEND").Append(i.ToString()).Append(" ").AppendLine(item.BlendFactor.ToString()); sb.Append("#define NORMAL_OP").Append(i.ToString()).Append(" ").AppendLine(((int)item.Operation).ToString()); } } if (settings.Specular != null) { for (var i = 0; i < settings.Specular.Length; i++) { var item = settings.Specular[0]; sb.Append("#define SPECULAR_INDEX").Append(i.ToString()).Append(" texCoord").AppendLine(item.Index.ToString()); sb.Append("#define SPECULAR_BLEND").Append(i.ToString()).Append(" ").AppendLine(item.BlendFactor.ToString()); sb.Append("#define SPECULAR_OP").Append(i.ToString()).Append(" ").AppendLine(((int)item.Operation).ToString()); } } if (settings.Emissive != null) { for (var i = 0; i < settings.Specular.Length; i++) { var item = settings.Specular[0]; sb.Append("#define EMISSIVE_INDEX").Append(i.ToString()).Append(" texCoord").AppendLine(item.Index.ToString()); sb.Append("#define EMISSIVE_BLEND").Append(i.ToString()).Append(" ").AppendLine(item.BlendFactor.ToString()); sb.Append("#define EMISSIVE_OP").Append(i.ToString()).Append(" ").AppendLine(((int)item.Operation).ToString()); } } sb.AppendLine(); }
Material[] ReadMaterials(BinaryReader reader, Dictionary <string, Texture> textures) { var matCount = reader.ReadInt32(); var mats = new MeshMaterial[matCount]; for (var i = 0; i < matCount; i++) { var name = reader.ReadString(); var mat = new MeshMaterial(null, name); mat.IsTwoSided = reader.ReadBoolean(); mat.IsWireframeEnabled = reader.ReadBoolean(); var shadingMode = (ShadingMode)reader.ReadInt32(); mat.BlendMode = (BlendMode)reader.ReadInt32(); mat.Opacity = reader.ReadSingle(); mat.Shininess = reader.ReadSingle(); mat.ShininessStrength = reader.ReadSingle(); mat.ColorAmbient = reader.ReadVector4(); mat.ColorDiffuse = reader.ReadVector4(); mat.ColorSpecular = reader.ReadVector4(); mat.ColorEmissive = reader.ReadVector4(); mat.ColorTransparent = reader.ReadVector4(); var boneCount = reader.ReadInt32(); var boneSlotCount = reader.ReadInt32(); mat.DiffuseMap = this.ReadTextureStack(reader, textures); mat.NormalMap = this.ReadTextureStack(reader, textures); mat.SpecularMap = this.ReadTextureStack(reader, textures); mat.EmissiveMap = this.ReadTextureStack(reader, textures); var settings = new MeshShaderSettings { MaxLights = 4, BoneCount = boneCount, BoneSlotCount = boneSlotCount, ShadingMode = shadingMode, Diffuse = GetMeshTextureStack(mat.DiffuseMap), Normal = GetMeshTextureStack(mat.NormalMap), Specular = GetMeshTextureStack(mat.SpecularMap), Emissive = GetMeshTextureStack(mat.EmissiveMap) }; mat.Shader = new MeshShader(settings); mats[i] = mat; } return(mats); }
static void AppendDefines (StringBuilder sb, MeshShaderSettings settings) { sb.Append("#define MAX_NUM_LIGHTS ").AppendLine(settings.MaxLights.ToString()); if (settings.Diffuse != null) { for (var i = 0; i < settings.Diffuse.Length; i++) { var item = settings.Diffuse[0]; sb.Append("#define DIFFUSE_INDEX").Append(i.ToString()).Append(" texCoord").AppendLine(item.Index.ToString()); sb.Append("#define DIFFUSE_BLEND").Append(i.ToString()).Append(" ").AppendLine(item.BlendFactor.ToString()); sb.Append("#define DIFFUSE_OP").Append(i.ToString()).Append(" ").AppendLine(((int)item.Operation).ToString()); } } if (settings.Normal != null) { for (var i = 0; i < settings.Normal.Length; i++) { var item = settings.Normal[0]; sb.Append("#define NORMAL_INDEX").Append(i.ToString()).Append(" texCoord").AppendLine(item.Index.ToString()); sb.Append("#define NORMAL_BLEND").Append(i.ToString()).Append(" ").AppendLine(item.BlendFactor.ToString()); sb.Append("#define NORMAL_OP").Append(i.ToString()).Append(" ").AppendLine(((int)item.Operation).ToString()); } } if (settings.Specular != null) { for (var i = 0; i < settings.Specular.Length; i++) { var item = settings.Specular[0]; sb.Append("#define SPECULAR_INDEX").Append(i.ToString()).Append(" texCoord").AppendLine(item.Index.ToString()); sb.Append("#define SPECULAR_BLEND").Append(i.ToString()).Append(" ").AppendLine(item.BlendFactor.ToString()); sb.Append("#define SPECULAR_OP").Append(i.ToString()).Append(" ").AppendLine(((int)item.Operation).ToString()); } } if (settings.Emissive != null) { for (var i = 0; i < settings.Specular.Length; i++) { var item = settings.Specular[0]; sb.Append("#define EMISSIVE_INDEX").Append(i.ToString()).Append(" texCoord").AppendLine(item.Index.ToString()); sb.Append("#define EMISSIVE_BLEND").Append(i.ToString()).Append(" ").AppendLine(item.BlendFactor.ToString()); sb.Append("#define EMISSIVE_OP").Append(i.ToString()).Append(" ").AppendLine(((int)item.Operation).ToString()); } } sb.AppendLine(); }
static void AppendVarying (StringBuilder sb, MeshShaderSettings settings, bool output) { sb.AppendLine("varying vec3 normal;"); sb.AppendLine("varying vec3 v;"); for (var i = 0; i < 4; i++) sb.Append("varying").Append(" vec2 texCoord").Append(i).AppendLine(";"); }
static void AppendAttribute (StringBuilder sb, MeshShaderSettings settings) { sb.AppendLine("attribute vec4 Position;"); sb.AppendLine("attribute vec4 Normal;"); for (var i = 0; i < 4; i++) sb.Append("attribute vec2 TexCoord").Append(i).AppendLine(";"); for (var i = 0; i < settings.BoneSlotCount; i++) { sb.Append("attribute float BoneWeight").Append(i).AppendLine(";"); sb.Append("attribute float BoneIndex").Append(i).AppendLine(";"); } }
static void AppendUniform (StringBuilder sb, MeshShaderSettings settings) { sb.AppendLine("uniform mat4 WorldViewProjection;"); sb.AppendLine("uniform mat4 WorldView;"); sb.AppendLine("uniform mat4 NormalMatrix;"); sb.AppendLine("uniform vec4 ColorAmbient;"); sb.AppendLine("uniform vec4 ColorDiffuse;"); sb.AppendLine("uniform vec4 ColorSpecular;"); sb.AppendLine("uniform vec4 ColorEmissive;"); sb.AppendLine("uniform float Shininess;"); sb.AppendLine("uniform float ShininessStrength;"); if (settings.Diffuse != null) { for (var i = 0; i < settings.Diffuse.Length; i++) sb.Append("uniform sampler2D DiffuseMap").Append(i.ToString()).AppendLine(";"); } if (settings.Normal != null) { for (var i = 0; i < settings.Normal.Length; i++) sb.Append("uniform sampler2D NormalMap").Append(i.ToString()).AppendLine(";"); } if (settings.Specular != null) { for (var i = 0; i < settings.Specular.Length; i++) sb.Append("uniform sampler2D SpecularMap").Append(i.ToString()).AppendLine(";"); } if (settings.Emissive != null) { for (var i = 0; i < settings.Emissive.Length; i++) sb.Append("uniform sampler2D EmissiveMap").Append(i.ToString()).AppendLine(";"); } if (settings.BoneCount > 0) sb.Append("uniform mat4 Bones[").Append(settings.BoneCount).AppendLine("];"); sb.AppendLine("uniform int NumLights;"); if (settings.MaxLights > 0) { sb.AppendLine("uniform int LightType[MAX_NUM_LIGHTS];"); sb.AppendLine("uniform vec3 LightVector[MAX_NUM_LIGHTS];"); sb.AppendLine("uniform vec3 LightAmbient[MAX_NUM_LIGHTS];"); sb.AppendLine("uniform vec3 LightDiffuse[MAX_NUM_LIGHTS];"); sb.AppendLine("uniform vec3 LightSpecular[MAX_NUM_LIGHTS];"); sb.AppendLine("uniform vec3 LightAttenuation[MAX_NUM_LIGHTS];"); } }
static string GetName(MeshShaderSettings settings) { return(typeof(MeshShader).FullName + "::" + settings.MaxLights); }
public MeshShader(MeshShaderSettings settings) : base(GetVertSource(settings), GetFragSource(settings), GetName(settings)) { _maxNumLights = settings.MaxLights; }
public MeshShader (MeshShaderSettings settings) : base(GetVertSource(settings), GetFragSource(settings)) { _maxNumLights = settings.MaxLights; }
Material[] ReadMaterials (BinaryReader reader, Dictionary<string, Texture> textures) { var matCount = reader.ReadInt32(); var mats = new MeshMaterial[matCount]; for (var i = 0; i < matCount; i++) { var name = reader.ReadString(); var mat = new MeshMaterial(null, name); mat.IsTwoSided = reader.ReadBoolean(); mat.IsWireframeEnabled = reader.ReadBoolean(); var shadingMode = (ShadingMode)reader.ReadInt32(); mat.BlendMode = (BlendMode)reader.ReadInt32(); mat.Opacity = reader.ReadSingle(); mat.Shininess = reader.ReadSingle(); mat.ShininessStrength = reader.ReadSingle(); mat.ColorAmbient = reader.ReadVector4(); mat.ColorDiffuse = reader.ReadVector4(); mat.ColorSpecular = reader.ReadVector4(); mat.ColorEmissive = reader.ReadVector4(); mat.ColorTransparent = reader.ReadVector4(); var boneCount = reader.ReadInt32(); var boneSlotCount = reader.ReadInt32(); mat.DiffuseMap = this.ReadTextureStack(reader, textures); mat.NormalMap = this.ReadTextureStack(reader, textures); mat.SpecularMap = this.ReadTextureStack(reader, textures); mat.EmissiveMap = this.ReadTextureStack(reader, textures); var settings = new MeshShaderSettings { MaxLights = 4, BoneCount = boneCount, BoneSlotCount = boneSlotCount, ShadingMode = shadingMode, Diffuse = GetMeshTextureStack(mat.DiffuseMap), Normal = GetMeshTextureStack(mat.NormalMap), Specular = GetMeshTextureStack(mat.SpecularMap), Emissive = GetMeshTextureStack(mat.EmissiveMap) }; mat.Shader = new MeshShader(settings); mats[i] = mat; } return mats; }