Пример #1
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);
            }
        }
Пример #2
0
        private void FinishMaterial(BatchInfo material)
        {
            DrawTechnique tech = material.Technique.Res;

            this.SetupBlendType(BlendMode.Reset);
            NativeShaderProgram.Bind(null as NativeShaderProgram);
            NativeTexture.ResetBinding();
        }
Пример #3
0
        private void FinishMaterial(BatchInfo material)
        {
            DrawTechnique tech = material.Technique.Res;

            this.FinishBlendState();
            NativeShaderProgram.Bind(null);
            NativeTexture.ResetBinding(this.sharedSamplerBindings);
        }
Пример #4
0
        /// <summary>
        /// Applies the specified parameter values to all currently active shaders.
        /// </summary>
        /// <param name="sharedParams"></param>
        /// <seealso cref="RetrieveActiveShaders"/>
        private void SetupSharedParameters(ShaderParameterCollection sharedParams)
        {
            this.sharedSamplerBindings = 0;
            this.sharedShaderParameters.Clear();
            if (sharedParams == null)
            {
                return;
            }

            foreach (NativeShaderProgram shader in this.activeShaders)
            {
                NativeShaderProgram.Bind(shader);

                ShaderFieldInfo[] varInfo   = shader.Fields;
                int[]             locations = shader.FieldLocations;

                // Setup shared sampler bindings and uniform data
                for (int i = 0; i < varInfo.Length; i++)
                {
                    ShaderFieldInfo field    = varInfo[i];
                    int             location = locations[i];

                    if (field.Scope == ShaderFieldScope.Attribute)
                    {
                        continue;
                    }
                    if (field.Type == ShaderFieldType.Sampler2D)
                    {
                        ContentRef <Texture> texRef;
                        if (!sharedParams.TryGetInternal(field.Name, out texRef))
                        {
                            continue;
                        }

                        NativeTexture.Bind(texRef, this.sharedSamplerBindings);
                        GL.Uniform1(location, this.sharedSamplerBindings);

                        this.sharedSamplerBindings++;
                    }
                    else
                    {
                        float[] data;
                        if (!sharedParams.TryGetInternal(field.Name, out data))
                        {
                            continue;
                        }

                        NativeShaderProgram.SetUniform(field, location, data);
                    }

                    this.sharedShaderParameters.Add(field.Name);
                }
            }

            NativeShaderProgram.Bind(null);
        }
Пример #5
0
		public static void Bind(NativeShaderProgram prog)
		{
			if (curBound == prog) return;

			if (prog == null)
			{
				GL.UseProgram(0);
				curBound = null;
			}
			else
			{
				GL.UseProgram(prog.Handle);
				curBound = prog;
			}
		}
Пример #6
0
        public static void Bind(NativeShaderProgram prog)
        {
            if (curBound == prog)
            {
                return;
            }

            if (prog == null)
            {
                GL.UseProgram(0);
                curBound = null;
            }
            else
            {
                GL.UseProgram(prog.Handle);
                curBound = prog;
            }
        }
Пример #7
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);
            }
        }
Пример #8
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();
                }
            }
        }
Пример #9
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;
                }
                }
            }
        }
Пример #10
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;
                }
                }
            }
        }
Пример #11
0
        private void SetupMaterial(BatchInfo material, BatchInfo lastMaterial)
        {
            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.SetupBlendState(tech.Blending);
            }

            // Bind Shader
            NativeShaderProgram nativeShader = tech.NativeShader as NativeShaderProgram;

            NativeShaderProgram.Bind(nativeShader);

            // Setup shader data
            ShaderFieldInfo[] varInfo   = nativeShader.Fields;
            int[]             locations = nativeShader.FieldLocations;

            // Setup sampler bindings and uniform data
            int curSamplerIndex = this.sharedSamplerBindings;

            for (int i = 0; i < varInfo.Length; i++)
            {
                ShaderFieldInfo field    = varInfo[i];
                int             location = locations[i];

                if (field.Scope == ShaderFieldScope.Attribute)
                {
                    continue;
                }
                if (this.sharedShaderParameters.Contains(field.Name))
                {
                    continue;
                }

                if (field.Type == ShaderFieldType.Sampler2D)
                {
                    ContentRef <Texture> texRef = material.GetInternalTexture(field.Name);
                    if (texRef == null)
                    {
                        this.internalShaderState.TryGetInternal(field.Name, out texRef);
                    }

                    NativeTexture.Bind(texRef, curSamplerIndex);
                    GL.Uniform1(location, curSamplerIndex);

                    curSamplerIndex++;
                }
                else
                {
                    float[] data = material.GetInternalData(field.Name);
                    if (data == null && !this.internalShaderState.TryGetInternal(field.Name, out data))
                    {
                        continue;
                    }

                    NativeShaderProgram.SetUniform(field, location, data);
                }
            }
            NativeTexture.ResetBinding(curSamplerIndex);
        }