/// <summary> /// Creates a material with the given name and shader /// </summary> /// <param name="name"></param> /// <param name="shadername"></param> /// <returns></returns> public Material CreateMaterial(string name, string shadername) { // Check if it's already loaded Material material; if (materialmap.TryGetValue(name, out material)) return material; // Create it material = new Material(Owner.GetComponent<Renderer>()); material.Name = name; material.Shader = GetShader(shadername); materialmap.Add(name, material); return material; }
/// <summary> /// Sets the current active material, returns true if a material switch occured /// </summary> /// <param name="material"></param> public void SetActiveMaterial(Material material, bool shadow = false, bool forceswitch = false, bool noapply = false) { // Null check if (material == null) { activematerial = null; activematerialshadow = false; return; } // Should we ignore optimisations? if (activematerial == null || forceswitch) { activematerial = material; Shader shader = shadow ? material.ShadowShader : material.Shader; if (shader == null) { activematerial = null; activematerialshadow = false; return; } shader.Activate(context); if (!noapply) material.Apply(shadow); frame_materialswitches++; frame_shaderswitches++; return; } // Did the material change? if (material != activematerial) { // Did the shader change? Shader oldshader = shadow ? activematerial.ShadowShader : activematerial.Shader; Shader newshader = shadow ? material.ShadowShader : material.Shader; if (newshader == null) { activematerial = null; activematerialshadow = false; return; } if (oldshader != newshader) { // Activate new shader newshader.Activate(context); frame_shaderswitches++; } // Apply activematerial = material; activematerialshadow = shadow; if (!noapply) material.Apply(shadow); frame_materialswitches++; } }
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(); }
/// <summary> /// Queues a draw order /// </summary> /// <param name="mesh"></param> /// <param name="submesh"></param> /// <param name="material"></param> /// <param name="transform"></param> public void QueueDraw(Mesh mesh, int submesh, Material material, Matrix transform) { // Create the work item RenderWorkItem item = workitempool.Request(); item.Mesh = mesh; item.SubmeshIndex = submesh; item.Material = material; item.Transform = transform; // Add to queue renderqueue.Add(item); }
private Actor LoadModel(JToken source) { // Create the actor Actor actor = new Actor(Owner.MessagePool); // Add the required components to it Transform transform = actor.AddComponent<Transform>(); // Load generic transform LoadTransform(transform, source); // Load model if (source["model"] != null) { string model = (string)source["model"]; SBMLoader loader = new SBMLoader("models/" + model + ".sbm"); string err; if (!loader.Load(out err)) { Console.WriteLine("Failed to load model '{0}'! ({1})", model, err); return null; } // Is there more than 1 mesh? if (loader.MeshCount > 1) { for (int i = 0; i < loader.MeshCount; i++) { Actor tmp = new Actor(Owner.MessagePool); tmp.AddComponent<Transform>(); MeshRenderer renderer = tmp.AddComponent<MeshRenderer>(); Mesh mesh; string[] materialnames; loader.GetMesh(i, out mesh, out materialnames); Material[] materials = new Material[materialnames.Length]; for (int j = 0; j < materials.Length; j++) { materials[j] = Owner.GetComponent<MaterialSystem>().GetMaterial(materialnames[j]); if (materials[j] == null) Console.WriteLine("Failed to load material '{0}'!", materialnames[j]); } renderer.Mesh = mesh; renderer.Materials = materials; tmp.Parent = actor; tmp.Init(); } } else { MeshRenderer renderer = actor.AddComponent<MeshRenderer>(); Mesh mesh; string[] materialnames; loader.GetMesh(0, out mesh, out materialnames); Material[] materials = new Material[materialnames.Length]; for (int j = 0; j < materials.Length; j++) materials[j] = Owner.GetComponent<MaterialSystem>().GetMaterial(materialnames[j]); renderer.Mesh = mesh; renderer.Materials = materials; } } // Initialise and return actor.Init(); return actor; }