Beispiel #1
0
        /// <summary>
        /// Calculates the bounding box of the whole model.
        /// </summary>
        private void ComputeBoundingBox(Model model, Scene scene)
        {
            var sceneMin = new Vector3(1e10f, 1e10f, 1e10f);
            var sceneMax = new Vector3(-1e10f, -1e10f, -1e10f);
            var transform = Matrix.Identity;

            ComputeBoundingBox(scene, scene.RootNode, ref sceneMin, ref sceneMax, ref transform);

            //set min and max of bounding box
            model.SetAxisAlignedBox(sceneMin, sceneMax);
        }
Beispiel #2
0
        public Model Load(string fileName)
        {
            Scene scene = _importer.ImportFile(fileName, PostProcessPreset.TargetRealTimeMaximumQuality);

            //use this directory path to load textures from
            _modelPath = Path.GetDirectoryName(fileName);

            var model = new Model();
            var identity = Matrix.Identity;

            AddVertexData(model, scene, scene.RootNode, _device, ref identity);
            ComputeBoundingBox(model, scene);

            return model;
        }
        public override WriteableBitmap Initialize(Device device)
		{
			const int width = 600;
			const int height = 400;

			// Create device and swap chain.
            var swapChainPresenter = new WpfSwapChainPresenter();
            _swapChain = device.CreateSwapChain(width, height, swapChainPresenter);
			_deviceContext = device.ImmediateContext;

			// Create RenderTargetView from the backbuffer.
			var backBuffer = Texture2D.FromSwapChain(_swapChain, 0);
			_renderTargetView = device.CreateRenderTargetView(backBuffer);

			// Compile Vertex and Pixel shaders
			var vertexShaderByteCode = ShaderCompiler.CompileFromFile("Modules/SampleBrowser/Samples/BasicTriangle/MiniTri.fx", "VS", "vs_4_0");
			var vertexShader = device.CreateVertexShader(vertexShaderByteCode);

            var pixelShaderByteCode = ShaderCompiler.CompileFromFile("Modules/SampleBrowser/Samples/BasicTriangle/MiniTri.fx", "PS", "ps_4_0");
			var pixelShader = device.CreatePixelShader(pixelShaderByteCode);

			// Layout from VertexShader input signature
			var layout = device.CreateInputLayout(
				new[]
				{
					new InputElement("POSITION", 0, Format.R32G32B32A32_Float, 0),
					new InputElement("COLOR", 0, Format.R32G32B32A32_Float, 0)
				}, vertexShaderByteCode);

			// Instantiate Vertex buffer from vertex data
			var vertices = device.CreateBuffer(new BufferDescription(BindFlags.VertexBuffer), new[]
			{
				new Vector4(0.0f, 0.5f, 0.5f, 1.0f), new Vector4(1.0f, 0.0f, 0.0f, 1.0f),
				new Vector4(0.5f, -0.5f, 0.5f, 1.0f), new Vector4(0.0f, 1.0f, 0.0f, 1.0f),
				new Vector4(-0.5f, -0.5f, 0.5f, 1.0f), new Vector4(0.0f, 0.0f, 1.0f, 1.0f)
			});

		    _model = new Model();
		    _model.AddMesh(new ModelMesh
		    {
		        IndexBuffer = device.CreateBuffer(new BufferDescription
		        {
		            BindFlags = BindFlags.IndexBuffer
		        }, new uint[] { 0, 1, 2 }),
                IndexCount = 3,
                InputLayout = layout,
                PrimitiveCount = 1,
                PrimitiveTopology = PrimitiveTopology.TriangleList,
                VertexBuffer = vertices,
                VertexCount = 3,
                VertexSize = 32
		    });

			// Prepare all the stages
			_deviceContext.VertexShader.Shader = vertexShader;
			_deviceContext.Rasterizer.SetViewports(new Viewport(0, 0, width, height, 0.0f, 1.0f));
			_deviceContext.PixelShader.Shader = pixelShader;
			_deviceContext.OutputMerger.SetTargets(null, _renderTargetView);

            return swapChainPresenter.Bitmap;
		}
        public override WriteableBitmap Initialize(Device device)
		{
            const int width = 600;
			const int height = 400;

			// Create device and swap chain.
            var swapChainPresenter = new WpfSwapChainPresenter();
            _swapChain = device.CreateSwapChain(width, height, swapChainPresenter);
			_deviceContext = device.ImmediateContext;

			// Create RenderTargetView from the backbuffer.
			var backBuffer = Texture2D.FromSwapChain(_swapChain, 0);
			_renderTargetView = device.CreateRenderTargetView(backBuffer);

			// Create the depth buffer
			var depthBuffer = device.CreateTexture2D(new Texture2DDescription
			{
				ArraySize = 1,
				MipLevels = 1,
				Width = width,
				Height = height,
				BindFlags = BindFlags.DepthStencil
			});

			// Create the depth buffer view
			_depthView = device.CreateDepthStencilView(depthBuffer);

            // Load model.
		    var modelLoader = new ModelLoader(device, TextureLoader.CreateTextureFromStream);
            _model = modelLoader.Load("Modules/SampleBrowser/Samples/ModelLoading/Car/car.obj");

            // Compile Vertex and Pixel shaders
            var vertexShaderByteCode = ShaderCompiler.CompileFromFile("Modules/SampleBrowser/Samples/ModelLoading/ModelLoading.fx", "VS", "vs_4_0");
            var vertexShader = device.CreateVertexShader(vertexShaderByteCode);

            var pixelShaderByteCode = ShaderCompiler.CompileFromFile("Modules/SampleBrowser/Samples/ModelLoading/ModelLoading.fx", "PS", "ps_4_0");
            var pixelShader = device.CreatePixelShader(pixelShaderByteCode);

		    _model.SetInputLayout(device, vertexShaderByteCode.InputSignature);

			var sampler = device.CreateSamplerState(new SamplerStateDescription
			{
				Filter = Filter.MinMagMipPoint,
				AddressU = TextureAddressMode.Wrap,
				AddressV = TextureAddressMode.Wrap,
				AddressW = TextureAddressMode.Wrap,
				BorderColor = Color4.Black,
				ComparisonFunction = Comparison.Never,
				MaximumAnisotropy = 16,
				MipLodBias = 0,
				MinimumLod = 0,
				MaximumLod = 16,
			});

            // Create constant buffers.
            _vertexConstantBuffer = device.CreateBuffer(new BufferDescription
            {
                SizeInBytes = Utilities.SizeOf<VertexShaderData>(),
                BindFlags = BindFlags.ConstantBuffer
            });
            _pixelConstantBuffer = device.CreateBuffer(new BufferDescription
            {
                SizeInBytes = Utilities.SizeOf<PixelShaderData>(),
                BindFlags = BindFlags.ConstantBuffer
            });

			// Prepare all the stages
            _deviceContext.VertexShader.SetConstantBuffers(0, _vertexConstantBuffer);
            _deviceContext.VertexShader.Shader = vertexShader;
            _deviceContext.PixelShader.SetConstantBuffers(0, _pixelConstantBuffer);
            _deviceContext.PixelShader.Shader = pixelShader;
			_deviceContext.PixelShader.SetSamplers(0, sampler);

            _vertexShaderData = new VertexShaderData();

            _pixelShaderData = new PixelShaderData
            {
                LightDirection = new Vector4(Vector3.Normalize(new Vector3(0.5f, 0, -1)), 1)
            };
            _deviceContext.SetBufferData(_pixelConstantBuffer, ref _pixelShaderData);

		    // Setup targets and viewport for rendering
			_deviceContext.Rasterizer.SetViewports(new Viewport(0, 0, width, height, 0.0f, 1.0f));
			_deviceContext.OutputMerger.SetTargets(_depthView, _renderTargetView);

            //_deviceContext.Rasterizer.State = device.CreateRasterizerState(new Pipeline.Rasterizer.RasterizerStateDescription
            //{
            //    FillMode = Pipeline.Rasterizer.FillMode.Wireframe
            //});

			// Prepare matrices
			_projection = Matrix.PerspectiveFovLH(MathUtil.Pi / 3.0f, 
				width / (float) height, 1f, 1000.0f);

            return swapChainPresenter.Bitmap;
		}
        public override WriteableBitmap Initialize(Device device)
		{
			// Create device and swap chain.
            var swapChainPresenter = new WpfSwapChainPresenter();
            _swapChain = device.CreateSwapChain(Width, Height, swapChainPresenter);
			_deviceContext = device.ImmediateContext;

			// Create RenderTargetView from the backbuffer.
			var backBuffer = Texture2D.FromSwapChain(_swapChain, 0);
			_renderTargetView = device.CreateRenderTargetView(backBuffer);

			// Create the depth buffer
			var depthBuffer = device.CreateTexture2D(new Texture2DDescription
			{
				ArraySize = 1,
				MipLevels = 1,
				Width = Width,
				Height = Height,
				BindFlags = BindFlags.DepthStencil
			});

			// Create the depth buffer view
			_depthView = device.CreateDepthStencilView(depthBuffer);

            // Create cube map resources.
            var cubeMapTexture = device.CreateTexture2D(new Texture2DDescription
            {
                Width = CubeMapSize,
                Height= CubeMapSize,
                ArraySize = 6,
                BindFlags = BindFlags.RenderTarget | BindFlags.ShaderResource,
                MipLevels = 1
            });
            _renderTargetViewCube = device.CreateRenderTargetView(cubeMapTexture);
            _resourceViewCube = device.CreateShaderResourceView(cubeMapTexture);
            var depthBufferCube = device.CreateTexture2D(new Texture2DDescription
            {
                ArraySize = 6,
                MipLevels = 1,
                Width = CubeMapSize,
                Height = CubeMapSize,
                BindFlags = BindFlags.DepthStencil
            });
            _depthViewCube = device.CreateDepthStencilView(depthBufferCube);

            // Load model.
		    var modelLoader = new ModelLoader(device, TextureLoader.CreateTextureFromStream);
            _model = modelLoader.Load("Modules/SampleBrowser/Samples/EnvironmentMapping/teapot.obj");

            // Compile Vertex and Pixel shaders
            var vertexShaderByteCode = ShaderCompiler.CompileFromFile("Modules/SampleBrowser/Samples/EnvironmentMapping/EnvironmentMapping.fx", "VS_CubeMap", "vs_4_0");
            _vertexShaderCubeMap = device.CreateVertexShader(vertexShaderByteCode);
            _vertexShaderStandard = device.CreateVertexShader(ShaderCompiler.CompileFromFile("Modules/SampleBrowser/Samples/EnvironmentMapping/EnvironmentMapping.fx", "VS_Standard", "vs_4_0"));

            _geometryShaderCubeMap = device.CreateGeometryShader(ShaderCompiler.CompileFromFile("Modules/SampleBrowser/Samples/EnvironmentMapping/EnvironmentMapping.fx", "GS_CubeMap", "gs_4_0"));

            _pixelShaderCubeMap = device.CreatePixelShader(ShaderCompiler.CompileFromFile("Modules/SampleBrowser/Samples/EnvironmentMapping/EnvironmentMapping.fx", "PS_CubeMap", "ps_4_0"));
            _pixelShaderStandard = device.CreatePixelShader(ShaderCompiler.CompileFromFile("Modules/SampleBrowser/Samples/EnvironmentMapping/EnvironmentMapping.fx", "PS_Standard", "ps_4_0"));
            _pixelShaderReflective = device.CreatePixelShader(ShaderCompiler.CompileFromFile("Modules/SampleBrowser/Samples/EnvironmentMapping/EnvironmentMapping.fx", "PS_Reflective", "ps_4_0"));

		    _model.SetInputLayout(device, vertexShaderByteCode.InputSignature);

            var sampler = device.CreateSamplerState(SamplerStateDescription.Default);

            // Create constant buffers.
            _vertexConstantBuffer = device.CreateBuffer(new BufferDescription
            {
                SizeInBytes = Utilities.SizeOf<VertexShaderData>(),
                BindFlags = BindFlags.ConstantBuffer
            });
            _geometryConstantBuffer = device.CreateBuffer(new BufferDescription
            {
                SizeInBytes = Utilities.SizeOf<GeometryShaderData>(),
                BindFlags = BindFlags.ConstantBuffer
            });
            var pixelConstantBuffer = device.CreateBuffer(new BufferDescription
            {
                SizeInBytes = Utilities.SizeOf<PixelShaderData>(),
                BindFlags = BindFlags.ConstantBuffer
            });

			// Prepare all the stages
            _deviceContext.VertexShader.SetConstantBuffers(0, _vertexConstantBuffer);
            _deviceContext.GeometryShader.SetConstantBuffers(0, _geometryConstantBuffer);
            _deviceContext.PixelShader.SetConstantBuffers(0, pixelConstantBuffer);
			_deviceContext.PixelShader.SetSamplers(0, sampler);

            _vertexShaderData = new VertexShaderData();

            _view1 = Matrix.LookAtLH(Vector3.Zero, new Vector3(1, 0, 0), Vector3.UnitY);
            _view2 = Matrix.LookAtLH(Vector3.Zero, new Vector3(-1, 0, 0), Vector3.UnitY);
            _view3 = Matrix.LookAtLH(Vector3.Zero, new Vector3(0, 1, 0), -Vector3.UnitZ);
            _view4 = Matrix.LookAtLH(Vector3.Zero, new Vector3(0, -1, 0), Vector3.UnitZ);
            _view5 = Matrix.LookAtLH(Vector3.Zero, new Vector3(0, 0, 1), Vector3.UnitY);
            _view6 = Matrix.LookAtLH(Vector3.Zero, new Vector3(0, 0, -1), Vector3.UnitY);

            var from = new Vector3(0, 30, 70);
            var to = new Vector3(0, 0, 0);

            // Prepare matrices
            var view = Matrix.LookAtLH(from, to, Vector3.UnitY);
            
			_projectionCube = Matrix.PerspectiveFovLH(MathUtil.PiOverTwo, 1.0f, 1f, 10000.0f);
            _projection = Matrix.PerspectiveFovLH(MathUtil.Pi / 3.0f, Width / (float) Height, 1f, 10000.0f);

            _viewProjectionCube = Matrix.Multiply(view, _projectionCube);
            _viewProjection = Matrix.Multiply(view, _projection);

            var pixelShaderData = new PixelShaderData
            {
                LightDirection = new Vector4(Vector3.Normalize(new Vector3(0.5f, 0, -1)), 1),
                EyePosition = new Vector4(from, 1)
            };
            _deviceContext.SetBufferData(pixelConstantBuffer, ref pixelShaderData);

            // Setup targets and viewport for rendering
            _deviceContext.Rasterizer.SetViewports(new Viewport(0, 0, Width, Height, 0.0f, 1.0f));
            _deviceContext.OutputMerger.SetTargets(_depthView, _renderTargetView);

            return swapChainPresenter.Bitmap;
		}
Beispiel #6
0
        /// <summary>
        /// Create meshes and add vertex and index buffers.
        /// </summary>
        private void AddVertexData(
            Model model, Scene scene, Node node, Device device,
            ref Matrix transform)
        {
            var previousTransform = transform;
            transform = Matrix.Multiply(previousTransform, node.Transform.ToMatrix());

            // Also calculate inverse transpose matrix for normal/tangent/bitagent transformation.
            var invTranspose = transform;
            invTranspose.Invert();
            invTranspose.Transpose();

            if (node.HasMeshes)
            {
                foreach (int index in node.MeshIndices)
                {
                    // Get a mesh from the scene.
                    Mesh mesh = scene.Meshes[index];

                    // Create new mesh to add to model.
                    var modelMesh = new ModelMesh();
                    model.AddMesh(modelMesh);

                    // If mesh has a material extract the diffuse texture, if present.
                    Material material = scene.Materials[mesh.MaterialIndex];
                    if (material != null && material.GetTextureCount(TextureType.Diffuse) > 0)
                    {
                        TextureSlot aiTexture = material.GetTexture(TextureType.Diffuse, 0);
                        using (var fileStream = File.OpenRead(_modelPath + "\\" + Path.GetFileName(aiTexture.FilePath)))
                        {
                            var texture = _textureLoadHandler(_device, fileStream);
                            modelMesh.AddTextureDiffuse(device, texture);
                        }
                    }

                    // Determine the elements in the vertex.
                    bool hasTexCoords = mesh.HasTextureCoords(0);
                    bool hasColors = mesh.HasVertexColors(0);
                    bool hasNormals = mesh.HasNormals;
                    bool hasTangents = mesh.Tangents != null;
                    bool hasBitangents = mesh.BiTangents != null;

                    // Create vertex element list.
                    var vertexElements = new InputElement[GetNumberOfInputElements(mesh)];
                    uint elementIndex = 0;
                    vertexElements[elementIndex++] = new InputElement("POSITION", 0, Format.R32G32B32_Float, 0, 0);
                    var vertexSize = (short) Utilities.SizeOf<Vector3>();

                    if (hasColors)
                    {
                        vertexElements[elementIndex++] = new InputElement("COLOR", 0, Format.R8G8B8A8_UInt, 0, vertexSize);
                        vertexSize += (short) Utilities.SizeOf<Color>();
                    }
                    if (hasNormals)
                    {
                        vertexElements[elementIndex++] = new InputElement("NORMAL", 0, Format.R32G32B32_Float, 0, vertexSize);
                        vertexSize += (short) Utilities.SizeOf<Vector3>();
                    }
                    if (hasTangents)
                    {
                        vertexElements[elementIndex++] = new InputElement("TANGENT", 0, Format.R32G32B32_Float, 0, vertexSize);
                        vertexSize += (short) Utilities.SizeOf<Vector3>();
                    }
                    if (hasBitangents)
                    {
                        vertexElements[elementIndex++] = new InputElement("BITANGENT", 0, Format.R32G32B32_Float, 0, vertexSize);
                        vertexSize += (short) Utilities.SizeOf<Vector3>();
                    }
                    if (hasTexCoords)
                    {
                        vertexElements[elementIndex++] = new InputElement("TEXCOORD", 0, Format.R32G32_Float, 0, vertexSize);
                        vertexSize += (short) Utilities.SizeOf<Vector2>();
                    }

                    //set the vertex elements and size
                    modelMesh.InputElements = vertexElements;
                    modelMesh.VertexSize = vertexSize;

                    //get pointers to vertex data
                    Vector3D[] positions = mesh.Vertices;
                    Vector3D[] texCoords = mesh.GetTextureCoords(0);
                    Vector3D[] normals = mesh.Normals;
                    Vector3D[] tangents = mesh.Tangents;
                    Vector3D[] biTangents = mesh.BiTangents;
                    Color4D[] colours = mesh.GetVertexColors(0);

                    //also determine primitive type
                    switch (mesh.PrimitiveType)
                    {
                        case PrimitiveType.Point:
                            modelMesh.PrimitiveTopology = PrimitiveTopology.PointList;
                            break;
                        case PrimitiveType.Line:
                            modelMesh.PrimitiveTopology = PrimitiveTopology.LineList;
                            break;
                        case PrimitiveType.Triangle:
                            modelMesh.PrimitiveTopology = PrimitiveTopology.TriangleList;
                            break;
                        default:
                            throw new Exception("ModelLoader::AddVertexData(): Unknown primitive type");
                    }

                    // Create new vertex buffer.
                    var vertexBuffer = device.CreateBuffer(
                        new BufferDescription
                        {
                            BindFlags = BindFlags.VertexBuffer,
                            SizeInBytes = mesh.VertexCount * vertexSize
                        });

                    int byteOffset = 0;
                    for (int i = 0; i < mesh.VertexCount; i++)
                    {
                        {
                            // Add position, after transforming it with accumulated node transform.
                            Vector4 tempResult;
                            Vector3 pos = positions[i].ToVector3();
                            Vector3.Transform(ref pos, ref transform, out tempResult);
                            var result = new Vector3(tempResult.X, tempResult.Y, tempResult.Z);
                            device.ImmediateContext.SetBufferData(vertexBuffer, ref result, byteOffset);
                            byteOffset += Vector3.SizeInBytes;
                        }

                        if (hasColors)
                        {
                            var vertColor = colours[i].ToColor();
                            device.ImmediateContext.SetBufferData(vertexBuffer, ref vertColor, byteOffset);
                            byteOffset += 4;
                        }
                        if (hasNormals)
                        {
                            var normal = normals[i].ToVector3();
                            Vector4 tempResult;
                            Vector3.Transform(ref normal, ref invTranspose, out tempResult);
                            var result = new Vector3(tempResult.X, tempResult.Y, tempResult.Z);
                            device.ImmediateContext.SetBufferData(vertexBuffer, ref result, byteOffset);
                            byteOffset += Vector3.SizeInBytes;
                        }
                        if (hasTangents)
                        {
                            var tangent = tangents[i].ToVector3();
                            Vector4 tempResult;
                            Vector3.Transform(ref tangent, ref invTranspose, out tempResult);
                            var result = new Vector3(tempResult.X, tempResult.Y, tempResult.Z);
                            device.ImmediateContext.SetBufferData(vertexBuffer, ref result, byteOffset);
                            byteOffset += Vector3.SizeInBytes;
                        }
                        if (hasBitangents)
                        {
                            var biTangent = biTangents[i].ToVector3();
                            Vector4 tempResult;
                            Vector3.Transform(ref biTangent, ref invTranspose, out tempResult);
                            var result = new Vector3(tempResult.X, tempResult.Y, tempResult.Z);
                            device.ImmediateContext.SetBufferData(vertexBuffer, ref result, byteOffset);
                            byteOffset += Vector3.SizeInBytes;
                        }
                        if (hasTexCoords)
                        {
                            var result = new Vector2(texCoords[i].X, 1 - texCoords[i].Y);
                            device.ImmediateContext.SetBufferData(vertexBuffer, ref result, byteOffset);
                            byteOffset += Vector2.SizeInBytes;
                        }
                    }

                    // Add it to the mesh.
                    modelMesh.VertexBuffer = vertexBuffer;
                    modelMesh.VertexCount = mesh.VertexCount;
                    modelMesh.PrimitiveCount = mesh.FaceCount;

                    // Get pointer to indices data.
                    var indices = mesh.GetIndices();

                    // Create new index buffer.
                    var indexBuffer = device.CreateBuffer(
                        new BufferDescription
                        {
                            BindFlags = BindFlags.IndexBuffer,
                            SizeInBytes = indices.Length * sizeof(uint)
                        }, indices);

                    // Add it to the mesh.
                    modelMesh.IndexBuffer = indexBuffer;
                    modelMesh.IndexCount = indices.Length;
                }
            }

            // If node has more children process them as well.
            for (var i = 0; i < node.ChildCount; i++)
                AddVertexData(model, scene, node.Children[i], device, ref transform);

            transform = previousTransform;
        }