/// <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); } }
/// <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); }
/// <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); }
/// <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) { }