private Material LoadMaterial(string name) { // Check the file exists string filename = string.Format("materials/{0}.txt", name); if (!File.Exists(filename)) { Console.WriteLine("Failed to load material {0} (file not found)!", name); return null; } // Load it string source = File.ReadAllText(filename); Console.WriteLine("Loading material {0}...", name); JObject root = JObject.Parse(source); // Define material and loop each parameter Material material = new Material(Owner.GetComponent<Renderer>()); material.Name = name; foreach (var obj in root) { switch (obj.Key) { case "shader": material.Shader = GetShader((string)obj.Value); if (material.Shader == null) { Console.WriteLine("Error loading material {0} - failed to load shader {1}!", name, (string)obj.Value); return null; } break; case "shadowshader": material.ShadowShader = GetShader((string)obj.Value); if (material.ShadowShader == null) { Console.WriteLine("Error loading material {0} - failed to load shader {1}!", name, (string)obj.Value); return null; } break; case "culling": string val = (string)obj.Value; switch (val) { case "frontface": material.CullingMode = Owner.GetComponent<Renderer>().Culling_Frontface; break; case "backface": material.CullingMode = Owner.GetComponent<Renderer>().Culling_Backface; break; case "none": material.CullingMode = Owner.GetComponent<Renderer>().Culling_None; break; } break; default: if (obj.Value.Type == JTokenType.Array) { int cnt = (obj.Value as JArray).Count; if (cnt == 3) material.SetParameter(obj.Key, new Vector3((float)obj.Value[0], (float)obj.Value[1], (float)obj.Value[2])); else if (cnt == 2) material.SetParameter(obj.Key, new Vector2((float)obj.Value[0], (float)obj.Value[1])); else Console.WriteLine("Parameter '{0}' in material {1} is not understood!", obj.Key, name); } else if (obj.Value.Type == JTokenType.Float) material.SetParameter(obj.Key, (float)obj.Value); else if (obj.Value.Type == JTokenType.String) { string value = (string)obj.Value; if (value.Length == 0) Console.WriteLine("Parameter '{0}' in material {1} is an emoty string!", obj.Key, name); else { // What type of object is it trying to indicate? if (value[0] == '$') { // Is it a scripted texture? string texturedata = value.Substring(1); string[] script = null; if (texturedata.Contains("$")) { string[] texturearray = texturedata.Split('$'); if (texturearray.Length != 2) { Console.WriteLine("Parameter '{0}' in material {1} has bad scripted texture data!"); } else { texturedata = texturearray[1]; if (texturearray[0].Contains(":")) script = texturearray[0].Split(':'); else script = new string[] { texturearray[0] }; } } // Texture Texture2D tex = GetTexture(texturedata); if (tex == null) Console.WriteLine("Parameter '{0}' in material {1} referenced an invalid texture!", obj.Key, name); else { // Apply script if (script != null && script.Length >= 1) { switch (script[0]) { case "normalmap_from_heightmap": var device = Owner.GetComponent<Renderer>().Device; Texture2D output = new Texture2D(device, tex.Description); output.DebugName = tex.DebugName + "_normals"; float height = 1.0f; if (script.Length > 1) float.TryParse(script[1], out height); Result result = Texture2D.ComputeNormalMap(device.ImmediateContext, tex, output, (NormalMapFlags)0, Channel.Red, height); if (result.IsFailure) Console.WriteLine("Failed to convert heightmap at '{0}' to normalmap in material {1}!", texturedata, name); else tex = output; break; } } // Apply parameter material.SetParameter(obj.Key, tex); } } else if (value[0] == '@') { // Sampler switch (value.Substring(1)) { case "wrap_linear": material.SetParameter(obj.Key, Owner.GetComponent<Renderer>().Sampler_Wrap); break; case "clamp_linear": material.SetParameter(obj.Key, Owner.GetComponent<Renderer>().Sampler_Clamp_Linear); break; } } else Console.WriteLine("Parameter '{0}' in material {1} is not understood!", obj.Key, name); } } break; } } // Return it return material; }
public void OnInitialise(InitialiseMessage msg) { // Initialise scene manager Console.WriteLine("Initialising scene manager..."); // Initialise messages queuemsg = new PopulateRenderQueue(); queuemsg.SceneManager = this; cameramsg = new PopulateCameraList(); cameramsg.Cameras = new OrderedList<Camera>(new CameraComparer()); cameramsg.ShadowCasters = new HashSet<ShadowCaster>(); lightmsg = new PopulateLightList(); lightmsg.Lights = new OrderedList<Light>(new LightComparer()); psysmsg = new PopulateParticleSystemList(); psysmsg.ParticleSystems = new List<ParticleSystem>(); // Create render queue workitempool = new ResourcePool<RenderWorkItem>(); renderqueue = new OrderedList<RenderWorkItem>(new RenderWorkItemComparer()); effectqueue = new OrderedList<PostProcessEffect>(new PostProcessEffectComparer()); // Setup GBuffer Renderer renderer = Owner.GetComponent<Renderer>(); gbuffer = renderer.CreateRenderTarget(1, "GBuffer"); gbuffer.ClearColour = new Color4(0.0f, 0.0f, 0.0f, 0.0f); gbuffer.AddDepthComponent(); gbuffer_colour = gbuffer.AddTextureComponent(); gbuffer_normal = gbuffer.AddTextureComponent(SlimDX.DXGI.Format.R32G32B32A32_Float); gbuffer_position = gbuffer.AddTextureComponent(SlimDX.DXGI.Format.R32G32B32A32_Float); gbuffer_material = gbuffer.AddTextureComponent(SlimDX.DXGI.Format.R32G32B32A32_Float); gbuffer.Finish(); // Setup light accumulation buffer lightaccum = renderer.CreateRenderTarget(1, "LightAccum"); lightaccum.ClearColour = new Color4(1.0f, 0.0f, 0.0f, 0.0f); lightaccum_diffuse = lightaccum.AddTextureComponent(SlimDX.DXGI.Format.R32G32B32A32_Float); lightaccum_specular = lightaccum.AddTextureComponent(SlimDX.DXGI.Format.R32G32B32A32_Float); lightaccum.Finish(); // Setup particle accumulation buffer particleaccum = renderer.CreateRenderTarget(1, "ParticleAccum"); particleaccum.ClearColour = new Color4(0.0f, 0.0f, 0.0f, 0.0f); particleaccum_colour = particleaccum.AddTextureComponent(); particleaccum.Finish(); // Setup swap buffers swapA = renderer.CreateRenderTarget(1, "SwapA"); swapA_colour = swapA.AddTextureComponent(); swapA.Finish(); swapB = renderer.CreateRenderTarget(1, "SwapB"); swapB_colour = swapB.AddTextureComponent(); swapB.Finish(); // Setup materials MaterialSystem matsys = Owner.GetComponent<MaterialSystem>(); mat_blit = matsys.CreateMaterial("blit", "blit"); mat_blit.SetParameter("smpTexture", renderer.Sampler_Clamp); mat_blitlight = matsys.CreateMaterial("blit_light", "blit_light"); mat_blitlight.SetParameter("smpTexture", renderer.Sampler_Clamp); mat_blitlight.SetParameter("texColour", gbuffer.GetTexture(gbuffer_colour)); mat_blitlight.SetParameter("texDiffuseLight", lightaccum.GetTexture(lightaccum_diffuse)); mat_blitlight.SetParameter("texSpecularLight", lightaccum.GetTexture(lightaccum_specular)); // Setup lights mat_lights = new Dictionary<LightType, Material>(); mat_lights.Add(LightType.Ambient, matsys.CreateMaterial("light_ambient", "light_ambient")); mat_lights.Add(LightType.Directional, matsys.CreateMaterial("light_directional", "light_directional")); mat_lights.Add(LightType.Point, matsys.CreateMaterial("light_point", "light_point")); foreach (Material mat in mat_lights.Values) { mat.SetParameter("texNormal", gbuffer.GetTexture(gbuffer_normal)); mat.SetParameter("texPosition", gbuffer.GetTexture(gbuffer_position)); mat.SetParameter("texMaterial", gbuffer.GetTexture(gbuffer_material)); mat.SetParameter("smpTexture", renderer.Sampler_Clamp); } // Setup meshes mesh_fs = MeshBuilder.BuildFullscreenQuad(); mesh_skybox = MeshBuilder.BuildCube(); }