public override void Draw(IDrawDevice device) { Texture mainTex = this.RetrieveMainTex(); ColorRgba mainClr = this.RetrieveMainColor(); DrawTechnique tech = this.RetrieveDrawTechnique(); Rect uvRect; if (mainTex != null) { uvRect = new Rect(mainTex.UVRatio.X, mainTex.UVRatio.Y); } else { uvRect = new Rect(1.0f, 1.0f); } this.PrepareVerticesLight(ref this.verticesLight, device, mainClr, uvRect, tech); if (this.customMat != null) { device.AddVertices(this.customMat, VertexMode.Quads, this.verticesLight); } else { device.AddVertices(this.sharedMat, VertexMode.Quads, this.verticesLight); } }
private void SetupVertexFormat(BatchInfo material, VertexDeclaration vertexDeclaration) { DrawTechnique technique = material.Technique.Res ?? DrawTechnique.Solid.Res; NativeShaderProgram nativeProgram = (technique.NativeShader ?? DrawTechnique.Solid.Res.NativeShader) as NativeShaderProgram; VertexElement[] elements = vertexDeclaration.Elements; for (int elementIndex = 0; elementIndex < elements.Length; elementIndex++) { int fieldIndex = nativeProgram.SelectField(ref elements[elementIndex]); if (fieldIndex == -1) { continue; } VertexAttribPointerType attribType; switch (elements[elementIndex].Type) { default: case VertexElementType.Float: attribType = VertexAttribPointerType.Float; break; case VertexElementType.Byte: attribType = VertexAttribPointerType.UnsignedByte; break; } int fieldLocation = nativeProgram.FieldLocations[fieldIndex]; GL.EnableVertexAttribArray(fieldLocation); GL.VertexAttribPointer( fieldLocation, elements[elementIndex].Count, attribType, true, vertexDeclaration.Size, elements[elementIndex].Offset); } }
/// <summary> /// Initializes Dualitys embedded default content. /// </summary> public static void InitDefaultContent() { if (defaultContentInitialized) { return; } Log.Core.Write("Initializing default content.."); Log.Core.PushIndent(); var oldResLib = resLibrary.Values.ToArray(); VertexShader.InitDefaultContent(); FragmentShader.InitDefaultContent(); ShaderProgram.InitDefaultContent(); DrawTechnique.InitDefaultContent(); Pixmap.InitDefaultContent(); Texture.InitDefaultContent(); Material.InitDefaultContent(); Font.InitDefaultContent(); // Make a list of all default content available foreach (var pair in resLibrary) { if (oldResLib.Contains(pair.Value)) { continue; } defaultContent.Add(pair.Value); } defaultContentInitialized = true; Log.Core.PopIndent(); Log.Core.Write("..done"); }
private void FinishVertexFormat(BatchInfo material, VertexDeclaration vertexDeclaration) { DrawTechnique technique = material.Technique.Res ?? DrawTechnique.Solid.Res; NativeShaderProgram program = (technique.Shader.Res != null ? technique.Shader.Res : ShaderProgram.Minimal.Res).Native as NativeShaderProgram; if (program == null) { return; } //VertexDeclaration vertexDeclaration = renderBatch.VertexDeclaration; //VertexElement[] elements = vertexDeclaration.Elements; ShaderFieldInfo[] varInfo = program.Fields; int[] locations = program.FieldLocations; for (int varIndex = 0; varIndex < varInfo.Length; varIndex++) { if (locations[varIndex] == -1) { continue; } GL.DisableVertexAttribArray(locations[varIndex]); } }
private void CreateProgram(FragmentShader frag, VertexShader vert) { Shader refShader = (vert != null) ? (Shader)vert : (Shader)frag; string nameTemp = refShader.Name; string dirTemp = Path.GetDirectoryName(refShader.Path); if (nameTemp.Contains("Shader")) { nameTemp = nameTemp.Replace("Shader", "Program"); } else if (nameTemp.Contains("Shader")) { nameTemp = nameTemp.Replace("shader", "program"); } else { nameTemp += "Program"; } string programPath = PathHelper.GetFreePath(Path.Combine(dirTemp, nameTemp), Resource.GetFileExtByType <DrawTechnique>()); DrawTechnique tech = new DrawTechnique(BlendMode.Mask, vert, frag); tech.Save(programPath); }
private void FinishMaterial(BatchInfo material) { DrawTechnique tech = material.Technique.Res; this.SetupBlendType(BlendMode.Reset); NativeShaderProgram.Bind(null as NativeShaderProgram); NativeTexture.ResetBinding(); }
private void FinishMaterial(BatchInfo material) { DrawTechnique tech = material.Technique.Res; this.FinishBlendState(); NativeShaderProgram.Bind(null); NativeTexture.ResetBinding(this.sharedSamplerBindings); }
public override void Draw(IDrawDevice device) { if (animHidden) { return; } Texture mainTex = RetrieveMainTex(); DrawTechnique tech = RetrieveDrawTechnique(); Rect uvRect, uvRectNext; bool smoothShaderInput = (tech != null && tech.PreferredVertexFormat == VertexC1P3T4A1.Declaration); GetAnimData(mainTex, smoothShaderInput, out uvRect, out uvRectNext); if (!smoothShaderInput) { PrepareVertices(ref vertices, device, this.colorTint, uvRect); if (customMat != null) { device.AddVertices(customMat, VertexMode.Quads, vertices, 0, 4); } else { if (flipMode == 0) { device.AddVertices(sharedMat, VertexMode.Quads, vertices, 0, 4); } else { BatchInfo material = device.RentMaterial(sharedMat.Res.Info); material.SetValue("normalMultiplier", new Vector2((flipMode & FlipMode.Horizontal) == 0 ? 1 : -1f, (flipMode & FlipMode.Vertical) == 0 ? 1 : -1f)); device.AddVertices(material, VertexMode.Quads, vertices, 0, 4); } } } else { PrepareVerticesSmooth(ref verticesSmooth, device, curAnimFrameFade, this.colorTint, uvRect, uvRectNext); if (customMat != null) { device.AddVertices(customMat, VertexMode.Quads, verticesSmooth, 0, 4); } else { if (flipMode == 0) { device.AddVertices(sharedMat, VertexMode.Quads, verticesSmooth, 0, 4); } else { BatchInfo material = device.RentMaterial(sharedMat.Res.Info); material.SetValue("normalMultiplier", new Vector2((flipMode & FlipMode.Horizontal) == 0 ? 1 : -1f, (flipMode & FlipMode.Vertical) == 0 ? 1 : -1f)); device.AddVertices(material, VertexMode.Quads, verticesSmooth, 0, 4); } } } }
/// <summary> /// Updates the internal list of active shaders based on the specified rendering batches. /// </summary> /// <param name="batches"></param> private void RetrieveActiveShaders(IReadOnlyList <DrawBatch> batches) { this.activeShaders.Clear(); for (int i = 0; i < batches.Count; i++) { DrawBatch batch = batches[i]; BatchInfo material = batch.Material; DrawTechnique tech = material.Technique.Res ?? DrawTechnique.Solid.Res; this.activeShaders.Add(tech.NativeShader as NativeShaderProgram); } }
/// <summary> /// Initializes Duality's embedded default content. /// </summary> public static void Init() { if (defaultContentInitialized) { return; } VertexShader.InitDefaultContent(); FragmentShader.InitDefaultContent(); DrawTechnique.InitDefaultContent(); Pixmap.InitDefaultContent(); Texture.InitDefaultContent(); Material.InitDefaultContent(); RenderSetup.InitDefaultContent(); defaultContentInitialized = true; }
private void FinishVertexFormat(BatchInfo material, VertexDeclaration vertexDeclaration) { DrawTechnique technique = material.Technique.Res ?? DrawTechnique.Solid.Res; NativeShaderProgram nativeProgram = (technique.NativeShader ?? DrawTechnique.Solid.Res.NativeShader) as NativeShaderProgram; VertexElement[] elements = vertexDeclaration.Elements; for (int elementIndex = 0; elementIndex < elements.Length; elementIndex++) { int fieldIndex = nativeProgram.SelectField(ref elements[elementIndex]); if (fieldIndex == -1) { break; } int fieldLocation = nativeProgram.FieldLocations[fieldIndex]; GL.DisableVertexAttribArray(fieldLocation); } }
public void Draw(IDrawDevice device, DrawTechnique technique) { if (CoreContext != null && _lastRenderFrame != Time.FrameCount) { RendererInterface.Device = device; RendererInterface.Technique = technique; if (CoreContext.Dimensions.X != (int)device.TargetSize.X || CoreContext.Dimensions.Y != (int)device.TargetSize.Y ) { CoreContext.Dimensions = new Vector2i((int)device.TargetSize.X, (int)device.TargetSize.Y); } CoreContext.Render(); _lastRenderFrame = Time.FrameCount; } }
public override void Draw(IDrawDevice device) { var origRect = rect; //base.Draw(device); // repeat type beam float numSections = Width / rect.W; // orig draw code Texture mainTex = this.RetrieveMainTex(); ColorRgba mainClr = this.RetrieveMainColor(); DrawTechnique tech = this.RetrieveDrawTechnique(); Rect uvRect; Rect uvRectNext; bool smoothShaderInput = tech != null && tech.PreferredVertexFormat == VertexC1P3T4A1.Declaration; this.GetAnimData(mainTex, tech, smoothShaderInput, out uvRect, out uvRectNext); }
/// <summary> /// Retrieves the internal representation of the specified variables numeric value. /// The returned array should be treated as read-only. /// </summary> /// <param name="name"></param> public float[] GetInternalData(string name) { // Retrieve the material parameter if available float[] result; if (this.parameters != null && this.parameters.TryGetInternal(name, out result)) { return(result); } // Fall back to the used techniques default parameter value DrawTechnique tech = this.technique.Res; if (tech != null && tech.DefaultParameters.TryGetInternal(name, out result)) { return(result); } return(null); }
/// <summary> /// Retrieves a copy of the values that are assigned the specified variable. If the internally /// stored type does not match the specified type, it will be converted before returning. /// </summary> /// <typeparam name="T"></typeparam> /// <param name="name"></param> /// <seealso cref="ShaderParameterCollection.TryGet"/> public T[] GetArray <T>(string name) where T : struct { // Retrieve the material parameter if available T[] result; if (this.parameters != null && this.parameters.TryGet(name, out result)) { return(result); } // Fall back to the used techniques default parameter value DrawTechnique tech = this.technique.Res; if (tech != null && tech.DefaultParameters.TryGet(name, out result)) { return(result); } return(null); }
public override void Draw(IDrawDevice device) { Texture mainTex = this.RetrieveMainTex(); ColorRgba mainClr = this.RetrieveMainColor(); DrawTechnique tech = this.RetrieveDrawTechnique(); Rect uvRect; if (mainTex != null) { if (this.rectMode == UVMode.WrapBoth) { uvRect = new Rect(mainTex.UVRatio.X * this.rect.W / mainTex.PixelWidth, mainTex.UVRatio.Y * this.rect.H / mainTex.PixelHeight); } else if (this.rectMode == UVMode.WrapHorizontal) { uvRect = new Rect(mainTex.UVRatio.X * this.rect.W / mainTex.PixelWidth, mainTex.UVRatio.Y); } else if (this.rectMode == UVMode.WrapVertical) { uvRect = new Rect(mainTex.UVRatio.X, mainTex.UVRatio.Y * this.rect.H / mainTex.PixelHeight); } else { uvRect = new Rect(mainTex.UVRatio.X, mainTex.UVRatio.Y); } } else { uvRect = new Rect(1.0f, 1.0f); } this.PrepareVerticesLight(ref this.verticesLight, device, mainClr, uvRect, tech); if (this.customMat != null) { device.AddVertices(this.customMat, VertexMode.Quads, this.verticesLight); } else { device.AddVertices(this.sharedMat, VertexMode.Quads, this.verticesLight); } }
/// <summary> /// Initializes all embedded default content in Duality and registers it in the <see cref="ContentProvider"/>. /// </summary> public static void Init() { Logs.Core.Write("Initializing default content..."); Logs.Core.PushIndent(); VertexShader.InitDefaultContent(); FragmentShader.InitDefaultContent(); DrawTechnique.InitDefaultContent(); Pixmap.InitDefaultContent(); Texture.InitDefaultContent(); Material.InitDefaultContent(); RenderSetup.InitDefaultContent(); Font.InitDefaultContent(); AudioData.InitDefaultContent(); Sound.InitDefaultContent(); Logs.Core.Write("...done!"); Logs.Core.PopIndent(); }
/// <summary> /// Retrieves a texture from the specified variable. /// </summary> /// <param name="name"></param> /// <seealso cref="ShaderParameterCollection.TryGet"/> public ContentRef <Texture> GetTexture(string name) { // Retrieve the material parameter if available ContentRef <Texture> result; if (this.parameters != null && this.parameters.TryGet(name, out result)) { return(result); } // Fall back to the used techniques default parameter value DrawTechnique tech = this.technique.Res; if (tech != null && tech.DefaultParameters.TryGet(name, out result)) { return(result); } return(null); }
protected void GetAnimData(Texture mainTex, DrawTechnique tech, bool smoothShaderInput, out Rect uvRect, out Rect uvRectNext) { this.UpdateVisibleFrames(); if (mainTex != null) { mainTex.LookupAtlas(this.curAnimFrame, out uvRect); if (smoothShaderInput) { mainTex.LookupAtlas(this.nextAnimFrame, out uvRectNext); } else { uvRectNext = uvRect; } } else { uvRect = uvRectNext = new Rect(1.0f, 1.0f); } }
public override void Draw(IDrawDevice device) { // When rendering a sprite that uses dynamic lighting, make sure to update // the devices shared / global lighting variables this frame Light.UpdateLighting(device); Texture mainTex = this.RetrieveMainTex(); DrawTechnique tech = this.RetrieveDrawTechnique(); Rect uvRect; this.GetUVRect(mainTex, this.spriteIndex, out uvRect); this.PrepareVerticesLight(ref this.verticesLight, device, this.colorTint, uvRect, tech); if (this.customMat != null) { device.AddVertices(this.customMat, VertexMode.Quads, this.verticesLight); } else { device.AddVertices(this.sharedMat, VertexMode.Quads, this.verticesLight); } }
public override void Draw(IDrawDevice device) { Texture mainTex = this.RetrieveMainTex(); ColorRgba mainClr = this.RetrieveMainColor(); DrawTechnique tech = this.RetrieveDrawTechnique(); Rect uvRect; Rect uvRectNext; bool smoothShaderInput = tech != null && tech.PreferredVertexFormat == VertexC1P3T4A1.Declaration; this.GetAnimData(mainTex, tech, smoothShaderInput, out uvRect, out uvRectNext); if (!smoothShaderInput) { this.PrepareVertices(ref this.vertices, device, mainClr, uvRect); if (this.customMat != null) { device.AddVertices(this.customMat, VertexMode.Quads, this.vertices); } else { device.AddVertices(this.sharedMat, VertexMode.Quads, this.vertices); } } else { this.PrepareVerticesSmooth(ref this.verticesSmooth, device, this.curAnimFrameFade, mainClr, uvRect, uvRectNext); if (this.customMat != null) { device.AddVertices(this.customMat, VertexMode.Quads, this.verticesSmooth); } else { device.AddVertices(this.sharedMat, VertexMode.Quads, this.verticesSmooth); } } }
protected override void OnUpdateFromObjects(object[] values) { base.OnUpdateFromObjects(values); if (values.Any(o => o != null)) { bool invokeSetter = false; IEnumerable <BatchInfo> batchInfos = null; DrawTechnique refTech = null; batchInfos = values.Cast <BatchInfo>(); refTech = batchInfos.NotNull().First().Technique.Res; // Retrieve data about shader variables ShaderVarInfo[] varInfoArray = null; if (refTech != null && refTech.Shader.IsAvailable) { varInfoArray = refTech.Shader.Res.VarInfo; } else { varInfoArray = new ShaderVarInfo[] { new ShaderVarInfo() }; varInfoArray[0].arraySize = 1; varInfoArray[0].glVarLoc = -1; varInfoArray[0].name = ShaderVarInfo.VarName_MainTex; varInfoArray[0].scope = ShaderVarScope.Uniform; varInfoArray[0].type = ShaderVarType.Sampler2D; } // Get rid of unused variables (This changes actual Resource data!) if (!this.ReadOnly) { foreach (BatchInfo info in batchInfos.NotNull()) { List <string> texRemoveSched = null; List <string> uniRemoveSched = null; if (info.Textures != null) { foreach (var pair in info.Textures) { if (!varInfoArray.Any(v => v.scope == ShaderVarScope.Uniform && v.type == ShaderVarType.Sampler2D && v.name == pair.Key)) { if (texRemoveSched == null) { texRemoveSched = new List <string>(); } texRemoveSched.Add(pair.Key); } } } if (info.Uniforms != null) { foreach (var pair in info.Uniforms) { if (!varInfoArray.Any(v => v.scope == ShaderVarScope.Uniform && v.type != ShaderVarType.Sampler2D && v.name == pair.Key)) { if (uniRemoveSched == null) { uniRemoveSched = new List <string>(); } uniRemoveSched.Add(pair.Key); } } } if (texRemoveSched != null) { foreach (string name in texRemoveSched) { info.SetTexture(name, ContentRef <Texture> .Null); } invokeSetter = true; } if (uniRemoveSched != null) { foreach (string name in uniRemoveSched) { info.SetUniform(name, null); } invokeSetter = true; } } } // Create BatchInfo variables according to Shader uniforms, if not existing yet if (!this.ReadOnly) { foreach (ShaderVarInfo varInfo in varInfoArray) { if (varInfo.scope != ShaderVarScope.Uniform) { continue; } // Set Texture variables if (varInfo.type == ShaderVarType.Sampler2D) { foreach (BatchInfo info in batchInfos.NotNull()) { if (info.GetTexture(varInfo.name).IsExplicitNull) { info.SetTexture(varInfo.name, Texture.White); invokeSetter = true; } } } // Set other uniform variables else { float[] uniformVal = varInfo.InitUniformData(); if (uniformVal != null) { foreach (BatchInfo info in batchInfos.NotNull()) { float[] oldVal = info.GetUniform(varInfo.name); if (oldVal == null) { info.SetUniform(varInfo.name, uniformVal); invokeSetter = true; } else if (oldVal.Length != uniformVal.Length) { for (int i = 0; i < Math.Min(oldVal.Length, uniformVal.Length); i++) { uniformVal[i] = oldVal[i]; } info.SetUniform(varInfo.name, uniformVal); invokeSetter = true; } } } } } } // Create editors according to existing variables var texDict = batchInfos.NotNull().First().Textures; var uniformDict = batchInfos.NotNull().First().Uniforms; Dictionary <string, PropertyEditor> oldEditors = new Dictionary <string, PropertyEditor>(this.shaderVarEditors); if (texDict != null) { foreach (var tex in texDict) { ShaderVarInfo varInfo = varInfoArray.FirstOrDefault(v => v.scope == ShaderVarScope.Uniform && v.name == tex.Key); if (!varInfo.IsEditorVisible) { continue; } string texName = varInfo.name; if (oldEditors.ContainsKey(texName)) { oldEditors.Remove(texName); } else { PropertyEditor e = this.ParentGrid.CreateEditor(typeof(ContentRef <Texture>), this); e.Getter = this.CreateTextureValueGetter(texName); e.Setter = !this.ReadOnly ? this.CreateTextureValueSetter(texName) : null; e.PropertyName = texName; this.shaderVarEditors[texName] = e; this.ParentGrid.ConfigureEditor(e); this.AddPropertyEditor(e); } } } if (uniformDict != null) { foreach (var uniform in uniformDict) { ShaderVarInfo varInfo = varInfoArray.FirstOrDefault(v => v.scope == ShaderVarScope.Uniform && v.name == uniform.Key); if (!varInfo.IsEditorVisible) { continue; } PropertyEditor e = this.CreateUniformEditor(varInfo); if (e != null) { if (oldEditors.ContainsValue(e)) { oldEditors.Remove(varInfo.name); } else { e.PropertyName = uniform.Key; this.shaderVarEditors[uniform.Key] = e; this.AddPropertyEditor(e); } } } } // Remove old editors that aren't needed anymore foreach (var pair in oldEditors) { if (this.shaderVarEditors[pair.Key] == pair.Value) { this.shaderVarEditors.Remove(pair.Key); } this.RemovePropertyEditor(pair.Value); } // If we actually changed (updated) data here, invoke the setter if (invokeSetter) { this.SetValues(batchInfos); if (!this.IsUpdating) { this.PerformGetValue(); } } } }
public ContentRef<DrawTechnique> RequestShader(string path) { #if MULTIPLAYER && SERVER return DrawTechnique.Solid; #else switch (path) { case "Solid": return DrawTechnique.Solid; case "Add": return DrawTechnique.Add; //case "Alpha": return DrawTechnique.Alpha; //case "Invert": return DrawTechnique.Invert; //case "Light": return DrawTechnique.Light; //case "Mask": return DrawTechnique.Mask; //case "Multiply": return DrawTechnique.Multiply; case "SharpAlpha": return DrawTechnique.SharpAlpha; case "Picking": return DrawTechnique.Picking; } ContentRef<DrawTechnique> shader; if (!cachedShaders.TryGetValue(path, out shader)) { #if UNCOMPRESSED_CONTENT string pathAbsolute = PathOp.Combine(DualityApp.DataDirectory, "Shaders", path + ".res"); #elif PLATFORM_ANDROID || PLATFORM_WASM string pathAbsolute = PathOp.Combine(DualityApp.DataDirectory, "Main.dz", "Shaders.ES30", path + ".res"); #else string pathAbsolute = PathOp.Combine(DualityApp.DataDirectory, "Main.dz", "Shaders", path + ".res"); #endif ShaderJson json; using (Stream s = FileOp.Open(pathAbsolute, FileAccessMode.Read)) { lock (jsonParser) { json = jsonParser.Parse<ShaderJson>(s); } } if (json.Fragment == null && json.Vertex == null) { switch (json.BlendMode) { default: case BlendMode.Solid: shader = DrawTechnique.Solid; break; case BlendMode.Mask: shader = DrawTechnique.Mask; break; case BlendMode.Add: shader = DrawTechnique.Add; break; case BlendMode.Alpha: shader = DrawTechnique.Alpha; break; case BlendMode.Multiply: shader = DrawTechnique.Multiply; break; case BlendMode.Light: shader = DrawTechnique.Light; break; case BlendMode.Invert: shader = DrawTechnique.Invert; break; } } else { #if FAIL_ON_SHADER_COMPILE_ERROR && PLATFORM_ANDROID requestShaderNesting++; #endif ContentRef<VertexShader> vertex; ContentRef<FragmentShader> fragment; try { if (json.Vertex == null) { vertex = VertexShader.Minimal; } else if (json.Vertex.StartsWith("#inherit ")) { string parentPath = json.Vertex.Substring(9).Trim(); ContentRef<DrawTechnique> parent = RequestShader(parentPath); vertex = parent.Res.Vertex; } else if (json.Vertex.StartsWith("#include ")) { string includePath = Path.Combine(DualityApp.DataDirectory, "Shaders", json.Vertex.Substring(9).Trim()); using (Stream s = FileOp.Open(includePath, FileAccessMode.Read)) using (StreamReader r = new StreamReader(s)) { vertex = new VertexShader(r.ReadToEnd()); } } else { vertex = new VertexShader(json.Vertex.TrimStart()); } if (json.Fragment == null) { fragment = FragmentShader.Minimal; } else if (json.Fragment.StartsWith("#inherit ")) { string parentPath = json.Fragment.Substring(9).Trim(); ContentRef<DrawTechnique> parent = RequestShader(parentPath); fragment = parent.Res.Fragment; } else if (json.Fragment.StartsWith("#include ")) { string includePath = Path.Combine(DualityApp.DataDirectory, "Shaders", json.Fragment.Substring(9).Trim()); using (Stream s = FileOp.Open(includePath, FileAccessMode.Read)) using (StreamReader r = new StreamReader(s)) { fragment = new FragmentShader(r.ReadToEnd()); } } else { fragment = new FragmentShader(json.Fragment.TrimStart()); } } finally { #if FAIL_ON_SHADER_COMPILE_ERROR && PLATFORM_ANDROID requestShaderNesting--; #endif } VertexDeclaration vertexFormat; switch (json.VertexFormat) { case "C1P3": vertexFormat = VertexC1P3.Declaration; break; case "C1P3T2": vertexFormat = VertexC1P3T2.Declaration; break; case "C1P3T4A1": vertexFormat = VertexC1P3T4A1.Declaration; break; default: vertexFormat = null; break; } DrawTechnique result = new DrawTechnique(json.BlendMode, vertex, fragment); result.PreferredVertexFormat = vertexFormat; #if FAIL_ON_SHADER_COMPILE_ERROR && PLATFORM_ANDROID if (requestShaderNesting == 0 && result.DeclaredFields.Count == 0) { Android.CrashHandlerActivity.ShowErrorDialog(new InvalidDataException("Shader \"" + path + "\" cannot be compiled on your device.")); } #endif shader = result; } cachedShaders[path] = shader; } return shader; #endif }
private void SetupMaterial(BatchInfo material, BatchInfo lastMaterial) { if (material == lastMaterial) { return; } DrawTechnique tech = material.Technique.Res ?? DrawTechnique.Solid.Res; DrawTechnique lastTech = lastMaterial != null ? lastMaterial.Technique.Res : null; // Prepare Rendering if (tech.NeedsPreparation) { material = new BatchInfo(material); tech.PrepareRendering(this.currentDevice, material); } // Setup BlendType if (lastTech == null || tech.Blending != lastTech.Blending) { this.SetupBlendType(tech.Blending, this.currentDevice.DepthWrite); } // Bind Shader NativeShaderProgram shader = (tech.Shader.Res != null ? tech.Shader.Res.Native : null) as NativeShaderProgram; NativeShaderProgram.Bind(shader); // Setup shader data if (shader != null) { ShaderFieldInfo[] varInfo = shader.Fields; int[] locations = shader.FieldLocations; int[] builtinIndices = shader.BuiltinVariableIndex; // Setup sampler bindings automatically int curSamplerIndex = 0; if (material.Textures != null) { for (int i = 0; i < varInfo.Length; i++) { if (locations[i] == -1) { continue; } if (varInfo[i].Type != ShaderFieldType.Sampler2D) { continue; } // Bind Texture ContentRef <Texture> texRef = material.GetTexture(varInfo[i].Name); NativeTexture.Bind(texRef, curSamplerIndex); GL.Uniform1(locations[i], curSamplerIndex); curSamplerIndex++; } } NativeTexture.ResetBinding(curSamplerIndex); // Transfer uniform data from material to actual shader if (material.Uniforms != null) { for (int i = 0; i < varInfo.Length; i++) { if (locations[i] == -1) { continue; } float[] data = material.GetUniform(varInfo[i].Name); if (data == null) { continue; } NativeShaderProgram.SetUniform(ref varInfo[i], locations[i], data); } } // Specify builtin shader variables, if requested float[] fieldValue = null; for (int i = 0; i < builtinIndices.Length; i++) { if (BuiltinShaderFields.TryGetValue(this.currentDevice, builtinIndices[i], ref fieldValue)) { NativeShaderProgram.SetUniform(ref varInfo[i], locations[i], fieldValue); } } } // Setup fixed function data else { // Fixed function texture binding if (material.Textures != null) { int samplerIndex = 0; foreach (var pair in material.Textures) { NativeTexture.Bind(pair.Value, samplerIndex); samplerIndex++; } NativeTexture.ResetBinding(samplerIndex); } else { NativeTexture.ResetBinding(); } } }
private void FinishRenderBatch(IDrawBatch renderBatch) { DrawTechnique technique = renderBatch.Material.Technique.Res ?? DrawTechnique.Solid.Res; NativeShaderProgram program = (technique.Shader.Res != null ? technique.Shader.Res.Native : null) as NativeShaderProgram; VertexDeclaration vertexDeclaration = renderBatch.VertexDeclaration; VertexElement[] elements = vertexDeclaration.Elements; for (int elementIndex = 0; elementIndex < elements.Length; elementIndex++) { switch (elements[elementIndex].Role) { case VertexElementRole.Position: { GL.DisableClientState(ArrayCap.VertexArray); break; } case VertexElementRole.TexCoord: { GL.DisableClientState(ArrayCap.TextureCoordArray); break; } case VertexElementRole.Color: { GL.DisableClientState(ArrayCap.ColorArray); break; } default: { if (program != null) { ShaderFieldInfo[] varInfo = program.Fields; int[] locations = program.FieldLocations; int selectedVar = -1; for (int varIndex = 0; varIndex < varInfo.Length; varIndex++) { if (locations[varIndex] == -1) { continue; } if (!ShaderVarMatches( ref varInfo[varIndex], elements[elementIndex].Type, elements[elementIndex].Count)) { continue; } selectedVar = varIndex; break; } if (selectedVar == -1) { break; } GL.DisableVertexAttribArray(locations[selectedVar]); } break; } } } }
private void PrepareRenderBatch(IDrawBatch renderBatch) { DrawTechnique technique = renderBatch.Material.Technique.Res ?? DrawTechnique.Solid.Res; NativeShaderProgram program = (technique.Shader.Res != null ? technique.Shader.Res.Native : null) as NativeShaderProgram; VertexDeclaration vertexDeclaration = renderBatch.VertexDeclaration; VertexElement[] elements = vertexDeclaration.Elements; for (int elementIndex = 0; elementIndex < elements.Length; elementIndex++) { switch (elements[elementIndex].Role) { case VertexElementRole.Position: { GL.EnableClientState(ArrayCap.VertexArray); GL.VertexPointer( elements[elementIndex].Count, VertexPointerType.Float, vertexDeclaration.Size, elements[elementIndex].Offset); break; } case VertexElementRole.TexCoord: { GL.EnableClientState(ArrayCap.TextureCoordArray); GL.TexCoordPointer( elements[elementIndex].Count, TexCoordPointerType.Float, vertexDeclaration.Size, elements[elementIndex].Offset); break; } case VertexElementRole.Color: { ColorPointerType attribType; switch (elements[elementIndex].Type) { default: case VertexElementType.Float: attribType = ColorPointerType.Float; break; case VertexElementType.Byte: attribType = ColorPointerType.UnsignedByte; break; } GL.EnableClientState(ArrayCap.ColorArray); GL.ColorPointer( elements[elementIndex].Count, attribType, vertexDeclaration.Size, elements[elementIndex].Offset); break; } default: { if (program != null) { ShaderFieldInfo[] varInfo = program.Fields; int[] locations = program.FieldLocations; int selectedVar = -1; for (int varIndex = 0; varIndex < varInfo.Length; varIndex++) { if (locations[varIndex] == -1) { continue; } if (!ShaderVarMatches( ref varInfo[varIndex], elements[elementIndex].Type, elements[elementIndex].Count)) { continue; } selectedVar = varIndex; break; } if (selectedVar == -1) { break; } VertexAttribPointerType attribType; switch (elements[elementIndex].Type) { default: case VertexElementType.Float: attribType = VertexAttribPointerType.Float; break; case VertexElementType.Byte: attribType = VertexAttribPointerType.UnsignedByte; break; } GL.EnableVertexAttribArray(locations[selectedVar]); GL.VertexAttribPointer( locations[selectedVar], elements[elementIndex].Count, attribType, false, vertexDeclaration.Size, elements[elementIndex].Offset); } break; } } } }
protected override void OnUpdateFromObjects(object[] values) { base.OnUpdateFromObjects(values); if (values.Any(o => o != null)) { IEnumerable <BatchInfo> batchInfos = values.Cast <BatchInfo>(); DrawTechnique refTech = batchInfos.NotNull().First().Technique.Res; // Retrieve a list of shader variables to edit IReadOnlyList <ShaderFieldInfo> shaderFields = null; if (refTech != null) { shaderFields = refTech.DeclaredFields; } else { shaderFields = EmptyShaderFields; } // Remove editors that are no longer needed or no longer match their shader field List <string> removeEditors = null; foreach (var pair in this.fieldEditors) { bool isMatchingEditor = shaderFields.Contains(pair.Value.Field) && pair.Value.Field.Name == pair.Key; if (!isMatchingEditor) { if (removeEditors == null) { removeEditors = new List <string>(); } removeEditors.Add(pair.Key); } } if (removeEditors != null) { foreach (string fieldName in removeEditors) { this.RemovePropertyEditor(this.fieldEditors[fieldName].Editor); this.fieldEditors.Remove(fieldName); } } // Create editors for fields that do not yet have a matching editor, or which // were removed because they did no longer match. int autoCreateEditorCount = 1; int displayedFieldIndex = -1; for (int i = 0; i < shaderFields.Count; i++) { ShaderFieldInfo field = shaderFields[i]; // Skip fields that shouldn't be displayed if (field.IsPrivate) { continue; } if (field.Scope != ShaderFieldScope.Uniform) { continue; } displayedFieldIndex++; // Skip fields that already have a matching editor if (this.fieldEditors.ContainsKey(field.Name)) { continue; } // Create a new editor for this field PropertyEditor editor; if (field.Type == ShaderFieldType.Sampler2D) { editor = this.CreateTextureEditor(field); } else { editor = this.CreateUniformEditor(field); } // Add and register this editor this.fieldEditors[field.Name] = new FieldEditorItem { Editor = editor, Field = field }; if (autoCreateEditorCount + displayedFieldIndex <= this.ChildEditors.Count) { this.AddPropertyEditor(editor, autoCreateEditorCount + displayedFieldIndex); } else { this.AddPropertyEditor(editor); } } } }
public override bool Convert(ConvertOperation convert) { List <object> results = new List <object>(); List <Material> availData = convert.Perform <Material>().ToList(); // Generate objects foreach (Material mat in availData) { if (convert.IsObjectHandled(mat)) { continue; } DrawTechnique tech = mat.Technique.Res; LightingTechnique lightTech = tech as LightingTechnique; if (tech == null) { continue; } bool isDynamicLighting = lightTech != null || tech.PreferredVertexFormat == VertexC1P3T2A4.VertexTypeIndex || tech.PreferredVertexFormat == VertexC1P3T4A4A1.VertexTypeIndex; if (!isDynamicLighting) { continue; } Texture mainTex = mat.MainTexture.Res; GameObject gameobj = convert.Result.OfType <GameObject>().FirstOrDefault(); if (mainTex == null || mainTex.AnimFrames == 0) { LightingSpriteRenderer sprite = convert.Result.OfType <LightingSpriteRenderer>().FirstOrDefault(); if (sprite == null && gameobj != null) { sprite = gameobj.GetComponent <LightingSpriteRenderer>(); } if (sprite == null) { sprite = new LightingSpriteRenderer(); } sprite.SharedMaterial = mat; if (mainTex != null) { sprite.Rect = Rect.AlignCenter(0.0f, 0.0f, mainTex.PixelWidth, mainTex.PixelHeight); } convert.SuggestResultName(sprite, mat.Name); results.Add(sprite); } else { LightingAnimSpriteRenderer sprite = convert.Result.OfType <LightingAnimSpriteRenderer>().FirstOrDefault(); if (sprite == null && gameobj != null) { sprite = gameobj.GetComponent <LightingAnimSpriteRenderer>(); } if (sprite == null) { sprite = new LightingAnimSpriteRenderer(); } sprite.SharedMaterial = mat; sprite.Rect = Rect.AlignCenter(0.0f, 0.0f, mainTex.PixelWidth / mainTex.AnimCols, mainTex.PixelHeight / mainTex.AnimRows); sprite.AnimDuration = 5.0f; sprite.AnimFrameCount = mainTex.AnimFrames; convert.SuggestResultName(sprite, mat.Name); results.Add(sprite); } convert.MarkObjectHandled(mat); } convert.AddResult(results); return(false); }
private void SetupVertexFormat(BatchInfo material, VertexDeclaration vertexDeclaration) { DrawTechnique technique = material.Technique.Res ?? DrawTechnique.Solid.Res; NativeShaderProgram program = (technique.Shader.Res != null ? technique.Shader.Res : ShaderProgram.Minimal.Res).Native as NativeShaderProgram; if (program == null) { return; } VertexElement[] elements = vertexDeclaration.Elements; ShaderFieldInfo[] varInfo = program.Fields; int[] locations = program.FieldLocations; bool[] varUsed = new bool[varInfo.Length]; for (int elementIndex = 0; elementIndex < elements.Length; elementIndex++) { int selectedVar = -1; for (int varIndex = 0; varIndex < varInfo.Length; varIndex++) { if (varUsed[varIndex]) { continue; } if (locations[varIndex] == -1 || varInfo[varIndex].Scope != ShaderFieldScope.Attribute) { varUsed[varIndex] = true; continue; } if (!ShaderVarMatches( ref varInfo[varIndex], elements[elementIndex].Type, elements[elementIndex].Count)) { continue; } //if (elements[elementIndex].Role != VertexElementRole.Unknown && varInfo[varIndex].Name != elements[elementIndex].Role.ToString()) { // continue; //} selectedVar = varIndex; varUsed[varIndex] = true; break; } if (selectedVar == -1) { continue; } VertexAttribPointerType attribType; switch (elements[elementIndex].Type) { default: case VertexElementType.Float: attribType = VertexAttribPointerType.Float; break; case VertexElementType.Byte: attribType = VertexAttribPointerType.UnsignedByte; break; } bool isNormalized = (elements[elementIndex].Role == VertexElementRole.Color); GL.EnableVertexAttribArray(locations[selectedVar]); GL.VertexAttribPointer( locations[selectedVar], elements[elementIndex].Count, attribType, isNormalized, vertexDeclaration.Size, elements[elementIndex].Offset); } }
private void SetupMaterial(BatchInfo material, BatchInfo lastMaterial) { if (material == lastMaterial) { return; } DrawTechnique tech = material.Technique.Res ?? DrawTechnique.Solid.Res; DrawTechnique lastTech = lastMaterial != null ? lastMaterial.Technique.Res : null; // Setup BlendType if (lastTech == null || tech.Blending != lastTech.Blending) { this.SetupBlendType(tech.Blending, this.currentDevice.DepthWrite); } // Bind Shader ShaderProgram shader = tech.Shader.Res ?? ShaderProgram.Minimal.Res; NativeShaderProgram nativeShader = shader.Native as NativeShaderProgram; NativeShaderProgram.Bind(nativeShader); // Setup shader data ShaderFieldInfo[] varInfo = nativeShader.Fields; int[] locations = nativeShader.FieldLocations; // Setup sampler bindings automatically int curSamplerIndex = this.sharedSamplerBindings; for (int i = 0; i < varInfo.Length; i++) { if (locations[i] == -1) { continue; } if (varInfo[i].Type != ShaderFieldType.Sampler2D) { continue; } if (this.sharedShaderParameters.Contains(varInfo[i].Name)) { continue; } ContentRef <Texture> texRef = material.GetInternalTexture(varInfo[i].Name); NativeTexture.Bind(texRef, curSamplerIndex); GL.Uniform1(locations[i], curSamplerIndex); curSamplerIndex++; } NativeTexture.ResetBinding(curSamplerIndex); // Setup uniform data for (int i = 0; i < varInfo.Length; i++) { if (locations[i] == -1) { continue; } if (varInfo[i].Type == ShaderFieldType.Sampler2D) { continue; } if (this.sharedShaderParameters.Contains(varInfo[i].Name)) { continue; } float[] data; if (varInfo[i].Name == "ModelView") { data = modelViewData; } else if (varInfo[i].Name == "Projection") { data = projectionData; } else { data = material.GetInternalData(varInfo[i].Name); if (data == null) { continue; } } NativeShaderProgram.SetUniform(ref varInfo[i], locations[i], data); } }