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);
            }
        }
Beispiel #2
0
        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");
        }
Beispiel #4
0
        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]);
            }
        }
Beispiel #5
0
        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);
        }
Beispiel #6
0
        private void FinishMaterial(BatchInfo material)
        {
            DrawTechnique tech = material.Technique.Res;

            this.SetupBlendType(BlendMode.Reset);
            NativeShaderProgram.Bind(null as NativeShaderProgram);
            NativeTexture.ResetBinding();
        }
Beispiel #7
0
        private void FinishMaterial(BatchInfo material)
        {
            DrawTechnique tech = material.Technique.Res;

            this.FinishBlendState();
            NativeShaderProgram.Bind(null);
            NativeTexture.ResetBinding(this.sharedSamplerBindings);
        }
Beispiel #8
0
        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);
                    }
                }
            }
        }
Beispiel #9
0
 /// <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);
     }
 }
Beispiel #10
0
        /// <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;
        }
Beispiel #11
0
        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;
            }
        }
Beispiel #13
0
        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);
        }
Beispiel #14
0
        /// <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);
        }
Beispiel #15
0
        /// <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);
            }
        }
Beispiel #17
0
        /// <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();
        }
Beispiel #18
0
        /// <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);
        }
Beispiel #19
0
 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);
     }
 }
Beispiel #20
0
        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);
            }
        }
Beispiel #21
0
        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);
                }
            }
        }
Beispiel #22
0
        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();
                    }
                }
            }
        }
Beispiel #23
0
        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
        }
Beispiel #24
0
        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();
                }
            }
        }
Beispiel #25
0
        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;
                }
                }
            }
        }
Beispiel #26
0
        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;
                }
                }
            }
        }
Beispiel #27
0
        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);
        }
Beispiel #29
0
        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);
            }
        }
Beispiel #30
0
        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);
            }
        }