Example #1
0
        protected override void CreateResources(ResourceFactory factory)
        {
            _projectionBuffer = factory.CreateBuffer(new BufferDescription(64, BufferUsage.UniformBuffer | BufferUsage.Dynamic));
            _viewBuffer       = factory.CreateBuffer(new BufferDescription(64, BufferUsage.UniformBuffer | BufferUsage.Dynamic));
            _worldBuffer      = factory.CreateBuffer(new BufferDescription(64, BufferUsage.UniformBuffer | BufferUsage.Dynamic));
            Matrix4x4 worldMatrix =
                Matrix4x4.CreateTranslation(0, 15000, -5000)
                * Matrix4x4.CreateRotationX(3 * MathF.PI / 2)
                * Matrix4x4.CreateScale(0.05f);

            _gd.UpdateBuffer(_worldBuffer, 0, ref worldMatrix);

            Shader vs = LoadShader(factory, "Animated", ShaderStages.Vertex, "VS");
            Shader fs = LoadShader(factory, "Animated", ShaderStages.Fragment, "FS");

            ResourceLayout layout = factory.CreateResourceLayout(new ResourceLayoutDescription(
                                                                     new ResourceLayoutElementDescription("Projection", ResourceKind.UniformBuffer, ShaderStages.Vertex),
                                                                     new ResourceLayoutElementDescription("View", ResourceKind.UniformBuffer, ShaderStages.Vertex),
                                                                     new ResourceLayoutElementDescription("World", ResourceKind.UniformBuffer, ShaderStages.Vertex),
                                                                     new ResourceLayoutElementDescription("Bones", ResourceKind.UniformBuffer, ShaderStages.Vertex),
                                                                     new ResourceLayoutElementDescription("SurfaceTex", ResourceKind.TextureReadOnly, ShaderStages.Fragment),
                                                                     new ResourceLayoutElementDescription("SurfaceSampler", ResourceKind.Sampler, ShaderStages.Fragment)));

            Texture texture = KtxFile.LoadTexture(
                _gd,
                factory,
                GetAssetPath("textures/goblin_bc3_unorm.ktx"),
                PixelFormat.BC3_UNorm);

            _texView = _factory.CreateTextureView(texture);

            VertexLayoutDescription vertexLayouts = new VertexLayoutDescription(
                new[]
            {
                new VertexElementDescription("Position", VertexElementSemantic.Position, VertexElementFormat.Float3),
                new VertexElementDescription("UV", VertexElementSemantic.TextureCoordinate, VertexElementFormat.Float2),
                new VertexElementDescription("BoneWeights", VertexElementSemantic.TextureCoordinate, VertexElementFormat.Float4),
                new VertexElementDescription("BoneIndices", VertexElementSemantic.TextureCoordinate, VertexElementFormat.UInt4),
            });

            GraphicsPipelineDescription gpd = new GraphicsPipelineDescription(
                BlendStateDescription.SingleOverrideBlend,
                DepthStencilStateDescription.DepthOnlyLessEqual,
                new RasterizerStateDescription(FaceCullMode.Back, PolygonFillMode.Solid, FrontFace.CounterClockwise, true, false),
                PrimitiveTopology.TriangleList,
                new ShaderSetDescription(new[] { vertexLayouts }, new[] { vs, fs }),
                layout,
                _gd.SwapchainFramebuffer.OutputDescription);

            _pipeline = factory.CreateGraphicsPipeline(ref gpd);

            const string  monsterAssetPath = "models/goblin.dae";
            AssimpContext ac = new AssimpContext();

            _scene = ac.ImportFile(GetAssetPath(monsterAssetPath), 0);
            _rootNodeInverseTransform = _scene.RootNode.Transform;
            _rootNodeInverseTransform.Inverse();

            _firstMesh = _scene.Meshes[0];
            AnimatedVertex[] vertices = new AnimatedVertex[_firstMesh.VertexCount];
            for (int i = 0; i < vertices.Length; i++)
            {
                vertices[i].Position = new Vector3(_firstMesh.Vertices[i].X, _firstMesh.Vertices[i].Y, _firstMesh.Vertices[i].Z);
                vertices[i].UV       = new Vector2(_firstMesh.TextureCoordinateChannels[0][i].X, _firstMesh.TextureCoordinateChannels[0][i].Y);
            }

            _animation = _scene.Animations[0];

            List <int> indices = new List <int>();

            foreach (Face face in _firstMesh.Faces)
            {
                if (face.IndexCount == 3)
                {
                    indices.Add(face.Indices[0]);
                    indices.Add(face.Indices[1]);
                    indices.Add(face.Indices[2]);
                }
            }

            for (uint boneID = 0; boneID < _firstMesh.BoneCount; boneID++)
            {
                Bone bone = _firstMesh.Bones[(int)boneID];
                _boneIDsByName.Add(bone.Name, boneID);
                foreach (VertexWeight weight in bone.VertexWeights)
                {
                    vertices[weight.VertexID].AddBone(boneID, weight.Weight);
                }
            }
            Array.Resize(ref _boneTransformations, _firstMesh.BoneCount);

            _bonesBuffer = _factory.CreateBuffer(new BufferDescription(
                                                     64 * 64, BufferUsage.UniformBuffer | BufferUsage.Dynamic));

            _rs = factory.CreateResourceSet(new ResourceSetDescription(layout,
                                                                       _projectionBuffer, _viewBuffer, _worldBuffer, _bonesBuffer, _texView, _gd.Aniso4xSampler));

            _indexCount = (uint)indices.Count;

            _vertexBuffer = _factory.CreateBuffer(new BufferDescription(
                                                      (uint)(vertices.Length * Unsafe.SizeOf <AnimatedVertex>()), BufferUsage.VertexBuffer));
            _gd.UpdateBuffer(_vertexBuffer, 0, vertices);

            _indexBuffer = _factory.CreateBuffer(new BufferDescription(
                                                     _indexCount * 4, BufferUsage.IndexBuffer));
            _gd.UpdateBuffer(_indexBuffer, 0, indices.ToArray());

            _cl                 = factory.CreateCommandList();
            _camera             = new Camera(_window.Width, _window.Height);
            _camera.Position    = new Vector3(0, 3, 5f);
            _camera.MoveSpeed   = 1000f;
            _camera.FarDistance = 100000;
        }