예제 #1
0
        private ModelMeshPart CreateModelMeshPartShaderMaterial(
            AssetLoadContext context,
            W3dMesh w3dMesh,
            W3dMaterialPass w3dMaterialPass,
            W3dShaderMaterial w3dShaderMaterial,
            ShaderMaterialShaderResources shaderResources)
        {
            var texCoords = new MeshShaderResources.MeshVertex.TexCoords[w3dMesh.Header.NumVertices];

            if (w3dMaterialPass.TexCoords != null)
            {
                for (var i = 0; i < texCoords.Length; i++)
                {
                    texCoords[i].UV0 = w3dMaterialPass.TexCoords.Items[i];
                }
            }

            var blendEnabled = false;

            var texCoordsVertexBuffer = AddDisposable(context.GraphicsDevice.CreateStaticBuffer(
                                                          texCoords,
                                                          BufferUsage.VertexBuffer));

            var material = shaderResources.GetCachedMaterial(w3dShaderMaterial, context);

            var materialPass = new MaterialPass(material, context.ShaderResources.MeshDepth.Material);

            return(new ModelMeshPart(
                       this,
                       texCoordsVertexBuffer,
                       0,
                       (uint)w3dMesh.Triangles.Items.Length * 3,
                       blendEnabled,
                       materialPass,
                       materialPass)); // TODO
        }
예제 #2
0
        private ModelMeshMaterialPass CreateModelMeshMaterialPassShaderMaterial(
            ContentManager contentManager,
            W3dMesh w3dMesh,
            W3dMaterialPass w3dMaterialPass,
            W3dShaderMaterial w3dShaderMaterial,
            Effect effect)
        {
            var texCoords = new MeshVertex.TexCoords[w3dMesh.Header.NumVertices];

            if (w3dMaterialPass.TexCoords != null)
            {
                for (var i = 0; i < texCoords.Length; i++)
                {
                    texCoords[i].UV0 = w3dMaterialPass.TexCoords[i];
                }
            }

            var meshParts = new List <ModelMeshPart>();

            // TODO: Extract state properties from shader material.
            var rasterizerState = RasterizerStateDescriptionUtility.DefaultFrontIsCounterClockwise;
            var depthState      = DepthStencilStateDescription.DepthOnlyLessEqual;
            var blendState      = BlendStateDescription.SingleDisabled;

            var material = new ShaderMaterial(contentManager, effect)
            {
                PipelineState = new EffectPipelineState(
                    rasterizerState,
                    depthState,
                    blendState,
                    RenderPipeline.GameOutputDescription)
            };

            var materialConstantsResourceBinding = effect.GetParameter("MaterialConstants").ResourceBinding;
            var materialConstantsBuffer          = AddDisposable(contentManager.GraphicsDevice.ResourceFactory.CreateBuffer(
                                                                     new BufferDescription(
                                                                         materialConstantsResourceBinding.Size,
                                                                         BufferUsage.UniformBuffer | BufferUsage.Dynamic)));

            var materialConstantsBytes = new byte[materialConstantsResourceBinding.Size];

            void setMaterialConstant <T>(string name, T value)
                where T : struct
            {
                var constantBufferField = materialConstantsResourceBinding.GetField(name);

                var valueBytes = StructInteropUtility.ToBytes(ref value);

                if (valueBytes.Length != constantBufferField.Size)
                {
                    throw new InvalidOperationException();
                }

                Buffer.BlockCopy(
                    valueBytes,
                    0,
                    materialConstantsBytes,
                    constantBufferField.Offset,
                    constantBufferField.Size);
            }

            foreach (var w3dShaderProperty in w3dShaderMaterial.Properties)
            {
                switch (w3dShaderProperty.PropertyType)
                {
                case W3dShaderMaterialPropertyType.Texture:
                    var texture = CreateTexture(contentManager, w3dShaderProperty.StringValue);
                    material.SetProperty(w3dShaderProperty.PropertyName, texture);
                    break;

                case W3dShaderMaterialPropertyType.Bool:
                    setMaterialConstant(w3dShaderProperty.PropertyName, w3dShaderProperty.Value.Bool);
                    break;

                case W3dShaderMaterialPropertyType.Color:
                    setMaterialConstant(w3dShaderProperty.PropertyName, w3dShaderProperty.Value.Color);
                    break;

                case W3dShaderMaterialPropertyType.Float:
                    setMaterialConstant(w3dShaderProperty.PropertyName, w3dShaderProperty.Value.Float);
                    break;

                case W3dShaderMaterialPropertyType.Vector2:
                    setMaterialConstant(w3dShaderProperty.PropertyName, w3dShaderProperty.Value.Vector2);
                    break;

                case W3dShaderMaterialPropertyType.Vector3:
                    setMaterialConstant(w3dShaderProperty.PropertyName, w3dShaderProperty.Value.Vector3);
                    break;

                case W3dShaderMaterialPropertyType.Int:
                    setMaterialConstant(w3dShaderProperty.PropertyName, w3dShaderProperty.Value.Int);
                    break;

                default:
                    throw new NotSupportedException();
                }
            }

            contentManager.GraphicsDevice.UpdateBuffer(materialConstantsBuffer, 0, materialConstantsBytes);
            material.SetProperty("MaterialConstants", materialConstantsBuffer);

            meshParts.Add(new ModelMeshPart(
                              0,
                              w3dMesh.Header.NumTris * 3,
                              material));

            return(new ModelMeshMaterialPass(
                       contentManager.GraphicsDevice,
                       texCoords,
                       meshParts));
        }
예제 #3
0
        private ModelMeshPart CreateModelMeshPartShaderMaterial(
            AssetLoadContext context,
            W3dMesh w3dMesh,
            W3dMaterialPass w3dMaterialPass,
            W3dShaderMaterial w3dShaderMaterial,
            ShaderMaterialShaderResources shaderResources)
        {
            var texCoords = new MeshShaderResources.MeshVertex.TexCoords[w3dMesh.Header.NumVertices];

            if (w3dMaterialPass.TexCoords != null)
            {
                for (var i = 0; i < texCoords.Length; i++)
                {
                    texCoords[i].UV0 = w3dMaterialPass.TexCoords.Items[i];
                }
            }

            // TODO: Extract state properties from shader material.

            var blendEnabled = false;

            var pipeline = shaderResources.Pipeline;

            var materialResourceSetBuilder = AddDisposable(new ShaderMaterialResourceSetBuilder(
                                                               context.GraphicsDevice,
                                                               shaderResources));

            foreach (var w3dShaderProperty in w3dShaderMaterial.Properties)
            {
                switch (w3dShaderProperty.PropertyType)
                {
                case W3dShaderMaterialPropertyType.Texture:
                    var texture = context.AssetStore.Textures.GetByName(w3dShaderProperty.StringValue);
                    materialResourceSetBuilder.SetTexture(w3dShaderProperty.PropertyName, texture);
                    break;

                case W3dShaderMaterialPropertyType.Bool:
                    materialResourceSetBuilder.SetConstant(w3dShaderProperty.PropertyName, w3dShaderProperty.Value.Bool);
                    break;

                case W3dShaderMaterialPropertyType.Float:
                    materialResourceSetBuilder.SetConstant(w3dShaderProperty.PropertyName, w3dShaderProperty.Value.Float);
                    break;

                case W3dShaderMaterialPropertyType.Vector2:
                    materialResourceSetBuilder.SetConstant(w3dShaderProperty.PropertyName, w3dShaderProperty.Value.Vector2);
                    break;

                case W3dShaderMaterialPropertyType.Vector3:
                    materialResourceSetBuilder.SetConstant(w3dShaderProperty.PropertyName, w3dShaderProperty.Value.Vector3);
                    break;

                case W3dShaderMaterialPropertyType.Vector4:
                    materialResourceSetBuilder.SetConstant(w3dShaderProperty.PropertyName, w3dShaderProperty.Value.Vector4);
                    break;

                case W3dShaderMaterialPropertyType.Int:
                    materialResourceSetBuilder.SetConstant(w3dShaderProperty.PropertyName, w3dShaderProperty.Value.Int);
                    break;

                default:
                    throw new NotSupportedException();
                }
            }

            var materialResourceSet = materialResourceSetBuilder.CreateResourceSet();

            var texCoordsVertexBuffer = AddDisposable(context.GraphicsDevice.CreateStaticBuffer(
                                                          texCoords,
                                                          BufferUsage.VertexBuffer));

            return(new ModelMeshPart(
                       texCoordsVertexBuffer,
                       0,
                       (uint)w3dMesh.Triangles.Items.Length * 3,
                       blendEnabled,
                       pipeline,
                       pipeline, // TODO
                       materialResourceSet));
        }
예제 #4
0
        private ModelMeshMaterialPass CreateModelMeshMaterialPassShaderMaterial(
            ContentManager contentManager,
            W3dMesh w3dMesh,
            W3dMaterialPass w3dMaterialPass,
            W3dShaderMaterial w3dShaderMaterial,
            Effect effect)
        {
            var texCoords = new MeshVertex.TexCoords[w3dMesh.Header.NumVertices];

            if (w3dMaterialPass.TexCoords != null)
            {
                for (var i = 0; i < texCoords.Length; i++)
                {
                    texCoords[i].UV0 = w3dMaterialPass.TexCoords.Items[i];
                }
            }

            var meshParts = new List <ModelMeshPart>();

            // TODO: Extract state properties from shader material.
            var rasterizerState = RasterizerStateDescriptionUtility.DefaultFrontIsCounterClockwise;
            var depthState      = DepthStencilStateDescription.DepthOnlyLessEqual;
            var blendState      = BlendStateDescription.SingleDisabled;

            var material = new ShaderMaterial(contentManager, effect)
            {
                PipelineState = new EffectPipelineState(
                    rasterizerState,
                    depthState,
                    blendState,
                    RenderPipeline.GameOutputDescription)
            };

            var materialConstantsBuilder = new ShaderMaterialConstantsBuilder(effect);

            foreach (var w3dShaderProperty in w3dShaderMaterial.Properties)
            {
                switch (w3dShaderProperty.PropertyType)
                {
                case W3dShaderMaterialPropertyType.Texture:
                    var texture = CreateTexture(contentManager, w3dShaderProperty.StringValue);
                    material.SetProperty(w3dShaderProperty.PropertyName, texture);
                    break;

                case W3dShaderMaterialPropertyType.Bool:
                    materialConstantsBuilder.SetConstant(w3dShaderProperty.PropertyName, w3dShaderProperty.Value.Bool);
                    break;

                case W3dShaderMaterialPropertyType.Float:
                    materialConstantsBuilder.SetConstant(w3dShaderProperty.PropertyName, w3dShaderProperty.Value.Float);
                    break;

                case W3dShaderMaterialPropertyType.Vector2:
                    materialConstantsBuilder.SetConstant(w3dShaderProperty.PropertyName, w3dShaderProperty.Value.Vector2);
                    break;

                case W3dShaderMaterialPropertyType.Vector3:
                    materialConstantsBuilder.SetConstant(w3dShaderProperty.PropertyName, w3dShaderProperty.Value.Vector3);
                    break;

                case W3dShaderMaterialPropertyType.Vector4:
                    materialConstantsBuilder.SetConstant(w3dShaderProperty.PropertyName, w3dShaderProperty.Value.Vector4);
                    break;

                case W3dShaderMaterialPropertyType.Int:
                    materialConstantsBuilder.SetConstant(w3dShaderProperty.PropertyName, w3dShaderProperty.Value.Int);
                    break;

                default:
                    throw new NotSupportedException();
                }
            }

            material.SetMaterialConstants(AddDisposable(materialConstantsBuilder.CreateBuffer()));

            meshParts.Add(new ModelMeshPart(
                              0,
                              w3dMesh.Header.NumTris * 3,
                              material,
                              _meshDepthMaterialShader));

            return(new ModelMeshMaterialPass(
                       contentManager.GraphicsDevice,
                       texCoords,
                       meshParts));
        }
예제 #5
0
        private ModelMeshMaterialPass CreateModelMeshMaterialPassShaderMaterial(
            ContentManager contentManager,
            W3dMesh w3dMesh,
            W3dMaterialPass w3dMaterialPass,
            W3dShaderMaterial w3dShaderMaterial,
            Effect effect)
        {
            var texCoords = new MeshVertex.TexCoords[w3dMesh.Header.NumVertices];

            if (w3dMaterialPass.TexCoords != null)
            {
                for (var i = 0; i < texCoords.Length; i++)
                {
                    texCoords[i].UV0 = w3dMaterialPass.TexCoords[i];
                }
            }

            var meshParts = new List <ModelMeshPart>();

            // TODO: Extract state properties from shader material.
            var rasterizerState = RasterizerStateDescription.CullBackSolid;
            var depthState      = DepthStencilStateDescription.Default;
            var blendState      = BlendStateDescription.Opaque;

            var material = new ShaderMaterial(effect);

            material.PipelineState = new EffectPipelineState(
                rasterizerState,
                depthState,
                blendState);

            var materialConstantsResourceBinding = effect.GetParameter("MaterialConstants").ResourceBinding;
            var materialConstantsBuffer          = AddDisposable(OpenSage.LowLevel.Graphics3D.Buffer.CreateDynamic(
                                                                     contentManager.GraphicsDevice,
                                                                     (uint)materialConstantsResourceBinding.ConstantBufferSizeInBytes,
                                                                     BufferBindFlags.ConstantBuffer));

            var materialConstantsBytes = new byte[materialConstantsResourceBinding.ConstantBufferSizeInBytes];

            void setMaterialConstant <T>(string name, T value)
                where T : struct
            {
                var constantBufferField = materialConstantsResourceBinding.GetConstantBufferField(name);

                var valueBytes = StructInteropUtility.ToBytes(ref value);

                if (valueBytes.Length != constantBufferField.Size)
                {
                    throw new InvalidOperationException();
                }

                System.Buffer.BlockCopy(
                    valueBytes,
                    0,
                    materialConstantsBytes,
                    constantBufferField.Offset,
                    constantBufferField.Size);
            }

            foreach (var w3dShaderProperty in w3dShaderMaterial.Properties)
            {
                switch (w3dShaderProperty.PropertyType)
                {
                case W3dShaderMaterialPropertyType.Texture:
                    var texture = CreateTexture(contentManager, w3dShaderProperty.StringValue);
                    material.SetProperty(w3dShaderProperty.PropertyName, texture);
                    break;

                case W3dShaderMaterialPropertyType.Bool:
                    setMaterialConstant(w3dShaderProperty.PropertyName, w3dShaderProperty.Value.Bool);
                    break;

                case W3dShaderMaterialPropertyType.Color:
                    setMaterialConstant(w3dShaderProperty.PropertyName, w3dShaderProperty.Value.Color);
                    break;

                case W3dShaderMaterialPropertyType.Float:
                    setMaterialConstant(w3dShaderProperty.PropertyName, w3dShaderProperty.Value.Float);
                    break;

                case W3dShaderMaterialPropertyType.Vector2:
                    setMaterialConstant(w3dShaderProperty.PropertyName, w3dShaderProperty.Value.Vector2);
                    break;

                case W3dShaderMaterialPropertyType.Vector3:
                    setMaterialConstant(w3dShaderProperty.PropertyName, w3dShaderProperty.Value.Vector3);
                    break;

                case W3dShaderMaterialPropertyType.Int:
                    setMaterialConstant(w3dShaderProperty.PropertyName, w3dShaderProperty.Value.Int);
                    break;

                default:
                    throw new NotSupportedException();
                }
            }

            materialConstantsBuffer.SetData(materialConstantsBytes);
            material.SetProperty("MaterialConstants", materialConstantsBuffer);

            meshParts.Add(new ModelMeshPart(
                              0,
                              w3dMesh.Header.NumTris * 3,
                              material));

            return(new ModelMeshMaterialPass(
                       contentManager.GraphicsDevice,
                       texCoords,
                       meshParts));
        }