Esempio n. 1
0
File: Mesh.cs Progetto: vvvv/stride
 /// <summary>
 /// Initializes a new instance of the <see cref="Mesh" /> class.
 /// </summary>
 /// <param name="meshDraw">The mesh draw.</param>
 /// <param name="parameters">The parameters.</param>
 /// <exception cref="System.ArgumentNullException">parameters</exception>
 public Mesh(MeshDraw meshDraw, ParameterCollection parameters)
 {
     if (meshDraw == null)
     {
         throw new ArgumentNullException("meshDraw");
     }
     if (parameters == null)
     {
         throw new ArgumentNullException("parameters");
     }
     Draw       = meshDraw;
     Parameters = parameters;
 }
Esempio n. 2
0
        private InputElementDescription[] PrepareInputElements(PipelineStateDescription pipelineState, MeshDraw drawData)
        {
            // Get the input elements already contained in the mesh's vertex buffers
            var availableInputElements = drawData.VertexBuffers.CreateInputElements();
            var inputElements          = new List <InputElementDescription>(availableInputElements);

            // In addition, add input elements for all attributes that are not contained in a bound buffer, but required by the shader
            foreach (var inputAttribute in pipelineState.EffectBytecode.Reflection.InputAttributes)
            {
                var inputElementIndex = FindElementBySemantic(availableInputElements, inputAttribute.SemanticName, inputAttribute.SemanticIndex);

                // Provided by any vertex buffer?
                if (inputElementIndex >= 0)
                {
                    continue;
                }

                inputElements.Add(new InputElementDescription
                {
                    AlignedByteOffset    = 0,
                    Format               = PixelFormat.R32G32B32A32_Float,
                    InputSlot            = drawData.VertexBuffers.Length,
                    InputSlotClass       = InputClassification.Vertex,
                    InstanceDataStepRate = 0,
                    SemanticIndex        = inputAttribute.SemanticIndex,
                    SemanticName         = inputAttribute.SemanticName,
                });
            }

            return(inputElements.ToArray());
        }
Esempio n. 3
0
        /// <inheritdoc/>
        public override void Draw(RenderDrawContext context, RenderView renderView, RenderViewStage renderViewStage, int startIndex, int endIndex)
        {
            var commandList = context.CommandList;

            foreach (var renderFeature in RenderFeatures)
            {
                renderFeature.Draw(context, renderView, renderViewStage, startIndex, endIndex);
            }

            // TODO: stackalloc?
            var descriptorSetsLocal = descriptorSets.Value;

            if (descriptorSetsLocal == null || descriptorSetsLocal.Length < EffectDescriptorSetSlotCount)
            {
                descriptorSetsLocal = descriptorSets.Value = new DescriptorSet[EffectDescriptorSetSlotCount];
            }

            MeshDraw currentDrawData = null;
            int      emptyBufferSlot = -1;

            for (int index = startIndex; index < endIndex; index++)
            {
                var renderNodeReference = renderViewStage.SortedRenderNodes[index].RenderNode;
                var renderNode          = GetRenderNode(renderNodeReference);

                var renderMesh = (RenderMesh)renderNode.RenderObject;
                var drawData   = renderMesh.ActiveMeshDraw;

                // Get effect
                // TODO: Use real effect slot
                var renderEffect = renderNode.RenderEffect;
                if (renderEffect.Effect == null)
                {
                    continue;
                }

                // Bind VB
                if (currentDrawData != drawData)
                {
                    for (int slot = 0; slot < drawData.VertexBuffers.Length; slot++)
                    {
                        var vertexBuffer = drawData.VertexBuffers[slot];
                        commandList.SetVertexBuffer(slot, vertexBuffer.Buffer, vertexBuffer.Offset, vertexBuffer.Stride);
                    }

                    // If the mesh's vertex buffers miss any input streams, an additional input binding will have been added to the pipeline state.
                    // We bind an additional empty vertex buffer to that slot handle those streams gracefully.
                    if (emptyBufferSlot != drawData.VertexBuffers.Length)
                    {
                        commandList.SetVertexBuffer(drawData.VertexBuffers.Length, emptyBuffer, 0, 0);
                        emptyBufferSlot = drawData.VertexBuffers.Length;
                    }

                    if (drawData.IndexBuffer != null)
                    {
                        commandList.SetIndexBuffer(drawData.IndexBuffer.Buffer, drawData.IndexBuffer.Offset, drawData.IndexBuffer.Is32Bit);
                    }
                    currentDrawData = drawData;
                }

                var resourceGroupOffset = ComputeResourceGroupOffset(renderNodeReference);

                // Update cbuffer
                renderEffect.Reflection.BufferUploader.Apply(context.CommandList, ResourceGroupPool, resourceGroupOffset);

                // Bind descriptor sets
                for (int i = 0; i < descriptorSetsLocal.Length; ++i)
                {
                    var resourceGroup = ResourceGroupPool[resourceGroupOffset++];
                    if (resourceGroup != null)
                    {
                        descriptorSetsLocal[i] = resourceGroup.DescriptorSet;
                    }
                }

                commandList.SetPipelineState(renderEffect.PipelineState);
                commandList.SetDescriptorSets(0, descriptorSetsLocal);

                // Draw
                if (drawData.IndexBuffer == null)
                {
                    if (renderMesh.InstanceCount > 0)
                    {
                        commandList.DrawInstanced(drawData.DrawCount, renderMesh.InstanceCount, drawData.StartLocation);
                    }
                    else
                    {
                        commandList.Draw(drawData.DrawCount, drawData.StartLocation);
                    }
                }
                else
                {
                    if (renderMesh.InstanceCount > 0)
                    {
                        commandList.DrawIndexedInstanced(drawData.DrawCount, renderMesh.InstanceCount, drawData.StartLocation);
                    }
                    else
                    {
                        commandList.DrawIndexed(drawData.DrawCount, drawData.StartLocation);
                    }
                }
            }
        }
        public void LoadAssetTest(Vector3 position)
        {
            // Create a new entity and add it to the scene.
            var entity = new Entity();

            var rootScene = SceneSystem.SceneInstance.RootScene;

            entity.Transform.RotationEulerXYZ = new Vector3(0, 20, 0);
            entity.Transform.Scale            = new Vector3(0.2f, 0.2f, 0.2f);
            entity.Transform.Position         = position;



            // Create a new model from code
            // https://doc.xenko.com/latest/en/manual/scripts/create-a-model-from-code.html

            // Create a model and assign it to the model component.
            var model = new Stride.Rendering.Model();

            entity.GetOrCreate <ModelComponent>().Model = model;

            // Add one or more meshes using geometric primitives (eg spheres or cubes).
            //var meshDraw = Stride.Graphics.GeometricPrimitives.GeometricPrimitive.Sphere.New(GraphicsDevice).ToMeshDraw();
            //var mesh = new Stride.Rendering.Mesh { Draw = meshDraw };
            //model.Meshes.Add(mesh);

            // create the Mesh
            // https://github.com/stride3d/stride/blob/master/sources/editor/Stride.Assets.Presentation/AssetEditors/Gizmos/LightSpotGizmo.cs#L168

            var CWD       = System.IO.Directory.GetCurrentDirectory();
            var assetBase = System.IO.Path.GetFullPath(System.IO.Path.Combine(CWD, @"..\..\..\DynLoadAssets\drone2\"));
            var assetPath = (System.IO.Path.Combine(assetBase, "Drone2.obj"));

            if (!System.IO.File.Exists(assetPath))
            {
                // not sure why, but DebugText.Print isn't working at the time of testing this...
                DebugText.Print("Cannot find wavefront OBJ file at : " + assetPath, new Int2(50, 50));
                return;
            }

            // load the wavefront OBJ file...
            var wfData = new SimpleScene.Util3d.WavefrontObjLoader(assetPath);

            // TODO: iterate over materials / multiple materials on the same mesh...
            {
                VertexPositionNormalTexture[] vertices;
                UInt32[] triIndices;
                Wavefront_VertexSoup_Stride3d.generateDrawIndexBuffer(wfData, wfData.materials[0], out triIndices, out vertices);

                // convert into a graphics VB / IB pair
                var vertexBuffer = Stride.Graphics.Buffer.Vertex.New(GraphicsDevice, vertices, GraphicsResourceUsage.Dynamic);
                var indexBuffer  = Stride.Graphics.Buffer.Index.New(GraphicsDevice, triIndices);

                // add them to the drawing
                var meshDraw = new Stride.Rendering.MeshDraw {
                    /* Vertex buffer and index buffer setup */
                    PrimitiveType = Stride.Graphics.PrimitiveType.TriangleList,
                    DrawCount     = triIndices.Length,
                    VertexBuffers = new[] { new VertexBufferBinding(vertexBuffer, VertexPositionNormalTexture.Layout, vertexBuffer.ElementCount) },
                    IndexBuffer   = new IndexBufferBinding(indexBuffer, true, triIndices.Length),
                };

                // GenerateTangentBinormal() won't work on a GPU buffer. It has to be run when the data is attached to a
                //    fake CPU buffer. (see build pipeline code)
                // meshDraw.GenerateTangentBinormal();

                var customMesh = new Stride.Rendering.Mesh {
                    Draw = meshDraw
                };


                // set the material index for this mesh
                // customMesh.MaterialIndex = 0;

                // add the mesh to the model
                model.Meshes.Add(customMesh);
            }


            // load a texture from a file
            // var diffuseTextureFilename = System.IO.Path.Combine(assetBase,wfData.materials[0].mtl.diffuseTextureResourceName);
            // var diffTexStream = System.IO.File.Open(diffuseTextureFilename,System.IO.FileMode.Open,System.IO.FileAccess.Read);
            // var diffuseTexture = Texture.Load(GraphicsDevice,diffTexStream);

            // TODO: handle null textures

            var diffuseTexture  = textureObjectForWfTex(System.IO.Path.Combine(assetBase, wfData.materials[0].mtl.diffuseTextureResourceName));
            var specularTexture = textureObjectForWfTex(System.IO.Path.Combine(assetBase, wfData.materials[0].mtl.specularTextureResourceName));
            var emissiveTexture = textureObjectForWfTex(System.IO.Path.Combine(assetBase, wfData.materials[0].mtl.ambientTextureResourceName));

            // note: bump/normal mapping won't won't work until Bitangents are calculated
            // var bumpTexture = textureObjectForWfTex(System.IO.Path.Combine(assetBase,wfData.materials[0].mtl.bumpTextureResourceName));


            var cc = new ComputeColor();

            #if (true)
            {  // load textures
                var materialDescription = new Stride.Rendering.Materials.MaterialDescriptor
                {
                    Attributes =
                    {
                        DiffuseModel = new MaterialDiffuseLambertModelFeature(),
                        Diffuse      = new MaterialDiffuseMapFeature(new ComputeTextureColor(diffuseTexture)),

                        SpecularModel = new MaterialSpecularMicrofacetModelFeature {
                        },
                        Specular      = new MaterialSpecularMapFeature {
                            SpecularMap   = new ComputeTextureColor(specularTexture)
                        },
                        MicroSurface      = new MaterialGlossinessMapFeature {
                            GlossinessMap = new ComputeFloat(0.7f)
                        },

                        Emissive          = new MaterialEmissiveMapFeature(new ComputeTextureColor(emissiveTexture)),


                        // note: normal maps won't work until bitangents are calculated
                        // https://gist.github.com/johang88/3f175b045c8e8b55fb815cc19e6128ba
                        // see TNBExtensions.GenerateTangentBinormal(this MeshDraw meshData)
                        //Surface = new MaterialNormalMapFeature {
                        //        NormalMap = new ComputeTextureColor(bumpTexture),
                        //        IsXYNormal = true,
                        //        ScaleAndBias = true,
                        //        },

                        // this is for a solid color rendering...
                        // Diffuse = new MaterialDiffuseMapFeature(new ComputeColor { Key = MaterialKeys.DiffuseValue }),
                    }
                };
                var material = Material.New(GraphicsDevice, materialDescription);
                material.Passes[0].Parameters.Set(MaterialKeys.EmissiveIntensity, 5.0f);
                model.Materials.Add(material);
            }
            #else
            // this is for solid color rendering...
            var material = Material.New(GraphicsDevice, new MaterialDescriptor());
            material.Passes[0].Parameters.Set(MaterialKeys.DiffuseValue, Color.Red);
            model.Materials.Add(material);
            #endif



            SceneSystem.SceneInstance.RootScene.Entities.Add(entity);
        }