/// <summary>
        /// Gets or creates the material resource for the given VertexStructure object.
        /// </summary>
        internal static MaterialResource GetOrCreateMaterialResourceAndEnsureLoaded(this ResourceDictionary resourceDict, VertexStructureSurface targetSurface)
        {
            MaterialResource materialResource = GetOrCreateMaterialResource(resourceDict, targetSurface);

            if (!materialResource.IsLoaded)
            {
                materialResource.LoadResource();
            }

            return(materialResource);
        }
        /// <summary>
        /// Applies the material to the given render state.
        /// </summary>
        /// <param name="renderState">Current render state</param>
        /// <param name="instancingMode">The instancing mode for which to apply the material.</param>
        /// <param name="previousMaterial">The previously applied material.</param>
        internal override void Apply(RenderState renderState, MaterialApplyInstancingMode instancingMode, MaterialResource previousMaterial)
        {
            D3D11.DeviceContext deviceContext = renderState.Device.DeviceImmediateContextD3D11;
            bool isResourceSameType           =
                (previousMaterial != null) &&
                (previousMaterial.ResourceType == base.ResourceType);

            // Apply local shader configuration
            if (m_cbPerMaterialDataChanged)
            {
                m_cbPerMaterial.SetData(
                    deviceContext,
                    new CBPerMaterial()
                {
                    ClipFactor               = m_clipFactor,
                    MaxClipDistance          = m_maxClipDistance,
                    Texture0Factor           = m_textureResource != null ? 1f : 0f,
                    AdjustTextureCoordinates = m_adjustTextureCoordinates ? 1f : 0f,
                    AddToAlpha               = m_addToAlpha,
                    MaterialDiffuseColor     = m_materialDiffuseColor
                });
                m_cbPerMaterialDataChanged = false;
            }

            // Apply sampler and constants
            if (!isResourceSameType)
            {
                deviceContext.PixelShader.SetSampler(0, m_defaultResources.GetSamplerState(TextureSamplerQualityLevel.Low));
            }
            deviceContext.PixelShader.SetConstantBuffer(3, m_cbPerMaterial.ConstantBuffer);
            deviceContext.VertexShader.SetConstantBuffer(3, m_cbPerMaterial.ConstantBuffer);

            // Set texture resource (if set)
            if ((m_textureResource != null) &&
                (renderState.ViewInformation.ViewConfiguration.ShowTexturesInternal))
            {
                deviceContext.PixelShader.SetShaderResource(0, m_textureResource.TextureView);
            }
            else
            {
                deviceContext.PixelShader.SetShaderResource(0, null);
            }

            // Set shader resources
            if (!isResourceSameType)
            {
                deviceContext.VertexShader.Set(m_vertexShader.VertexShader);
                deviceContext.PixelShader.Set(m_pixelShader.PixelShader);
            }
        }
Пример #3
0
        /// <summary>
        /// Builds vertex and index buffers.
        /// </summary>
        /// <param name="device">The device on which to build all buffers.</param>
        /// <param name="structures">All structure to be loaded.</param>
        /// <param name="resources">The current resource dictionary</param>
        protected virtual LoadedStructureInfo[] BuildBuffers(EngineDevice device, VertexStructure[] structures, ResourceDictionary resources)
        {
            List <LoadedStructureInfo> result         = new List <LoadedStructureInfo>(structures.Length * 2);
            List <StandardVertex[]>    cachedVertices = new List <StandardVertex[]>(2);
            List <int[]> cachedIndices = new List <int[]>(6);

            int structuresCount = structures.Length;
            int actVertexCount  = 0;
            int actIndexCount   = 0;
            int lastFinishedVertexBufferResultIndex = -1;
            int lastFinishedIndexBufferResultIndex  = -1;
            int vertexBufferID = 0;
            int indexBufferID  = 0;

            // Define the action which finishes current index buffer
            Action actionFinishIndexBuffer = () =>
            {
                // Create the vertex buffer
                D3D11.Buffer indexBuffer = GraphicsHelper.CreateImmutableIndexBuffer(
                    device,
                    cachedIndices.ToArray());
                cachedIndices.Clear();
                actIndexCount = 0;
                indexBufferID++;

                // Do also create index buffer
                for (int loop = lastFinishedIndexBufferResultIndex + 1; loop < result.Count; loop++)
                {
                    result[loop].IndexBuffer = indexBuffer;
                }
                lastFinishedIndexBufferResultIndex = result.Count - 1;
            };

            // Define the action which finishes current vertex buffer
            Action actionFinishVertexBuffer = () =>
            {
                // Create the vertex buffer
                D3D11.Buffer vertexBuffer = GraphicsHelper.CreateImmutableVertexBuffer(
                    device,
                    cachedVertices.ToArray());
                cachedVertices.Clear();
                actVertexCount = 0;
                vertexBufferID++;

                // Do also finish index buffers in this case
                actionFinishIndexBuffer();

                // Do also create index buffer
                for (int loop = lastFinishedVertexBufferResultIndex + 1; loop < result.Count; loop++)
                {
                    result[loop].VertexBuffer = vertexBuffer;
                }
                lastFinishedVertexBufferResultIndex = result.Count - 1;
            };

            // Load all structures into memory within a loop
            for (int loopStruct = 0; loopStruct < structuresCount; loopStruct++)
            {
                VertexStructure actStructure = structures[loopStruct];
                if (actStructure.CountVertices == 0)
                {
                    continue;
                }
                if (actStructure.CountSurfaces == 0)
                {
                    continue;
                }

                // Handle vertex data
                StandardVertex[] vertexArray = StandardVertex.FromVertexStructure(actStructure);
                if (actVertexCount + vertexArray.Length > MAX_VERTEX_COUNT_PER_BUFFER)
                {
                    actionFinishVertexBuffer();
                }
                cachedVertices.Add(vertexArray);
                int actBaseVertex = actVertexCount;
                actVertexCount += vertexArray.Length;

                // Sort all surfaces by material
                List <VertexStructureSurface> surfaceList = new List <VertexStructureSurface>(actStructure.Surfaces);
                surfaceList.Sort((left, right) => left.MaterialProperties.GetHashCode().CompareTo(right.MaterialProperties.GetHashCode()));

                int surfaceCount = surfaceList.Count;
                for (int loopSurface = 0; loopSurface < surfaceCount; loopSurface++)
                {
                    VertexStructureSurface actSurface = surfaceList[loopSurface];
                    if (actSurface.CountTriangles == 0)
                    {
                        continue;
                    }

                    // Handle index data
                    int[] indexArray = actSurface.GetIndexArray();
                    if (actBaseVertex > 0)
                    {
                        for (int loopIndex = 0; loopIndex < indexArray.Length; loopIndex++)
                        {
                            indexArray[loopIndex] = indexArray[loopIndex] + actBaseVertex;
                        }
                    }
                    if (actIndexCount + indexArray.Length > MAX_INDEX_COUNT_PER_BUFFER)
                    {
                        actionFinishIndexBuffer();
                    }
                    cachedIndices.Add(indexArray);
                    actIndexCount += indexArray.Length;

                    // Get or create the material
                    LoadedStructureInfo lastStructureInfo = result.Count > 0 ? result[result.Count - 1] : null;
                    if ((lastStructureInfo != null) &&
                        (lastStructureInfo.IndexBuffer == null) &&
                        (actSurface.MaterialProperties.Equals(lastStructureInfo.MaterialProperties)))
                    {
                        LoadedStructureInfo actStructureInfo = result[result.Count - 1];
                        actStructureInfo.IndexCount = actStructureInfo.IndexCount + indexArray.Length;
                    }
                    else
                    {
                        MaterialResource actMaterialResource = resources.GetOrCreateMaterialResourceAndEnsureLoaded(actSurface);

                        // Create some information about the loaded structures
                        LoadedStructureInfo newStructureInfo = new LoadedStructureInfo();
                        newStructureInfo.VertexBufferID     = vertexBufferID;
                        newStructureInfo.IndexBufferID      = indexBufferID;
                        newStructureInfo.SizePerVertex      = StandardVertex.Size;
                        newStructureInfo.VertexStructure    = actStructure;
                        newStructureInfo.IndexCount         = indexArray.Length;
                        newStructureInfo.StartIndex         = actIndexCount - indexArray.Length;
                        newStructureInfo.Material           = actMaterialResource;
                        newStructureInfo.MaterialProperties = actSurface.MaterialProperties;
                        newStructureInfo.VertexBuffer       = null;
                        newStructureInfo.IndexBuffer        = null;
                        newStructureInfo.InputLayout        = newStructureInfo.Material.GenerateInputLayout(
                            device, StandardVertex.InputElements, MaterialApplyInstancingMode.SingleObject);
                        result.Add(newStructureInfo);
                    }
                }
            }

            // Finish all remaining buffers finally
            if (cachedVertices.Count > 0)
            {
                actionFinishVertexBuffer();
            }
            if (cachedIndices.Count > 0)
            {
                actionFinishIndexBuffer();
            }

            return(result.ToArray());
        }
        /// <summary>
        /// Applies the material to the given render state.
        /// </summary>
        /// <param name="renderState">Current render state</param>
        /// <param name="instancingMode">The instancing mode for which to apply the material.</param>
        /// <param name="previousMaterial">The previously applied material.</param>
        /// <exception cref="SeeingSharpGraphicsException">Effect  + this.Effect +  not supported!</exception>
        internal override void Apply(RenderState renderState, MaterialApplyInstancingMode instancingMode, MaterialResource previousMaterial)
        {
            D3D11.DeviceContext deviceContext = renderState.Device.DeviceImmediateContextD3D11;
            bool isResourceSameType           =
                (previousMaterial != null) &&
                (previousMaterial.ResourceType == base.ResourceType);

            if (!isResourceSameType)
            {
                deviceContext.PixelShader.SetSampler(0, m_defaultResources.GetSamplerState(TextureSamplerQualityLevel.Low));
            }

            // Set texture resource (if set)
            if (m_textureResource != null)
            {
                deviceContext.PixelShader.SetShaderResource(0, m_textureResource.TextureView);
            }
            else
            {
                deviceContext.PixelShader.SetShaderResource(0, null);
            }

            // Set shader resources
            deviceContext.VertexShader.Set(m_vertexShader.VertexShader);
            deviceContext.PixelShader.Set(m_pixelShader.PixelShader);
        }
Пример #5
0
        /// <summary>
        /// Applies the material to the given render state.
        /// </summary>
        /// <param name="renderState">Current render state</param>
        /// <param name="instancingMode">The instancing mode for which to apply the material.</param>
        /// <param name="previousMaterial">The previously applied material.</param>
        internal override void Apply(RenderState renderState, MaterialApplyInstancingMode instancingMode, MaterialResource previousMaterial)
        {
            D3D11.DeviceContext deviceContext = renderState.Device.DeviceImmediateContextD3D11;

            // Apply local shader configuration
            if (m_cbPerMaterialDataChanged)
            {
                m_cbPerMaterial.SetData(
                    deviceContext,
                    new CBPerMaterial()
                {
                    FadeIntensity = m_fadeIntensity
                });
                m_cbPerMaterialDataChanged = false;
            }

            // Apply constants and shader resources
            deviceContext.VertexShader.Set(m_vertexShader.VertexShader);
            deviceContext.PixelShader.Set(m_pixelShader.PixelShader);
            deviceContext.PixelShader.SetConstantBuffer(3, m_cbPerMaterial.ConstantBuffer);
            deviceContext.VertexShader.SetConstantBuffer(3, m_cbPerMaterial.ConstantBuffer);
        }
Пример #6
0
 /// <summary>
 /// Applies the material to the given render state.
 /// </summary>
 /// <param name="renderState">Current render state</param>
 /// <param name="instancingMode">The instancing mode for which to apply the material.</param>
 /// <param name="previousMaterial">The previously applied material.</param>
 internal virtual void Apply(RenderState renderState, MaterialApplyInstancingMode instancingMode, MaterialResource previousMaterial)
 {
 }