void RenderLight(Light light)
        {
            lightWorldVar.SetMatrixTranspose(light.World);
            lightPositionRadiusVar.Set(new Vector4(light.Position, light.Radius));
            lightColorVar.Set(light.Color);
            lightAccumulationPass.Apply(_immediateContext);

            _immediateContext.DrawIndexed(pointLightVolumeIndices.Length, 0, 0);
        }
Example #2
0
        public override void Initialize()
        {
            Form.SizeChanged += (o, args) =>
            {
                if (_swapChain == null)
                {
                    return;
                }

                renderView.Dispose();
                depthView.Dispose();
                DisposeBuffers();

                if (Form.WindowState == FormWindowState.Minimized)
                {
                    return;
                }

                _width  = Form.ClientSize.Width;
                _height = Form.ClientSize.Height;
                _swapChain.ResizeBuffers(_swapChain.Description.BufferCount, 0, 0, Format.Unknown, 0);

                CreateBuffers();
                SetSceneConstants();
            };

            _width     = 1024;
            _height    = 768;
            _nearPlane = 0.1f;

            try
            {
                OnInitializeDevice();
            }
            catch (Exception e)
            {
                MessageBox.Show(e.ToString(), "Could not create DirectX 11 device.");
                return;
            }


            // shader.fx

            const ShaderFlags shaderFlags = ShaderFlags.None;

            //const ShaderFlags shaderFlags = ShaderFlags.Debug | ShaderFlags.SkipOptimization;

            string[] sources = { "shader.fx", "grender.fx" };
            using (var shaderByteCode = ShaderLoader.FromResource(Assembly.GetExecutingAssembly(), sources, shaderFlags))
            {
                effect = new Effect(Device, shaderByteCode);
            }
            EffectTechnique technique = effect.GetTechniqueByName("GBufferCreate");

            shadowGenPass  = technique.GetPassByName("ShadowMap");
            gBufferGenPass = technique.GetPassByName("GBufferGen");
            debugDrawPass  = technique.GetPassByName("DebugDraw");

            var sceneConstantsDesc = new BufferDescription
            {
                SizeInBytes    = Marshal.SizeOf(typeof(ShaderSceneConstants)),
                Usage          = ResourceUsage.Dynamic,
                BindFlags      = BindFlags.ConstantBuffer,
                CpuAccessFlags = CpuAccessFlags.Write,
                OptionFlags    = ResourceOptionFlags.None
            };

            sceneConstantsBuffer = new Buffer(Device, sceneConstantsDesc);
            EffectConstantBuffer effectConstantBuffer = effect.GetConstantBufferByName("scene");

            effectConstantBuffer.SetConstantBuffer(sceneConstantsBuffer);

            var _rasterizerStateDesc = new RasterizerStateDescription
            {
                CullMode             = CullMode.None,
                FillMode             = FillMode.Solid,
                DepthBias            = 0,
                DepthBiasClamp       = 0,
                SlopeScaledDepthBias = 0,
                IsDepthClipEnabled   = true,
            };

            noCullState = new RasterizerState(Device, _rasterizerStateDesc);
            _rasterizerStateDesc.CullMode = CullMode.Back;
            backCullState = new RasterizerState(Device, _rasterizerStateDesc);
            _rasterizerStateDesc.CullMode = CullMode.Front;
            frontCullState = new RasterizerState(Device, _rasterizerStateDesc);
            _immediateContext.Rasterizer.State = CullingEnabled ? backCullState : noCullState;

            var depthDesc = new DepthStencilStateDescription
            {
                IsDepthEnabled   = true,
                IsStencilEnabled = false,
                DepthWriteMask   = DepthWriteMask.All,
                DepthComparison  = Comparison.Less
            };

            depthState = new DepthStencilState(Device, depthDesc);
            depthDesc.DepthWriteMask     = DepthWriteMask.Zero;
            outsideLightVolumeDepthState = new DepthStencilState(Device, depthDesc);
            depthDesc.DepthComparison    = Comparison.Greater;
            insideLightVolumeDepthState  = new DepthStencilState(Device, depthDesc);

            var lightDepthStateDesc = new DepthStencilStateDescription
            {
                IsDepthEnabled   = true,
                IsStencilEnabled = false,
                DepthWriteMask   = DepthWriteMask.All,
                DepthComparison  = Comparison.Less
            };

            lightDepthStencilState = new DepthStencilState(Device, lightDepthStateDesc);


            // grender.fx
            technique               = effect.GetTechniqueByName("DeferredShader");
            gBufferRenderPass       = technique.GetPassByName("DeferredShader");
            gBufferPostProcessPass  = technique.GetPassByName("Blur");
            gBufferPostProcessPass2 = technique.GetPassByName("PostProcess");
            gBufferOverlayPass      = technique.GetPassByName("Overlay");

            lightBufferVar            = effect.GetVariableByName("lightBuffer").AsShaderResource();
            normalBufferVar           = effect.GetVariableByName("normalBuffer").AsShaderResource();
            diffuseBufferVar          = effect.GetVariableByName("diffuseBuffer").AsShaderResource();
            depthMapVar               = effect.GetVariableByName("depthMap").AsShaderResource();
            shadowLightDepthBufferVar = effect.GetVariableByName("lightDepthMap").AsShaderResource();

            sunLightDirectionVar = effect.GetVariableByName("SunLightDirection").AsVector();
            viewportWidthVar     = effect.GetVariableByName("ViewportWidth").AsScalar();
            viewportHeightVar    = effect.GetVariableByName("ViewportHeight").AsScalar();
            viewParametersVar    = effect.GetVariableByName("ViewParameters").AsVector();

            overlayViewProjectionVar = effect.GetVariableByName("OverlayViewProjection").AsMatrix();


            // light.fx
            using (var shaderByteCode = ShaderLoader.FromResource(Assembly.GetExecutingAssembly(), "light.fx", shaderFlags))
            {
                lightShader = new Effect(Device, shaderByteCode);
            }

            technique             = lightShader.GetTechniqueByIndex(0);
            lightAccumulationPass = technique.GetPassByName("Light");

            lightWorldVar          = lightShader.GetVariableByName("World").AsMatrix();
            lightPositionRadiusVar = lightShader.GetVariableByName("PositionRadius").AsVector();
            lightColorVar          = lightShader.GetVariableByName("Color").AsVector();

            lightProjectionVar     = lightShader.GetVariableByName("Projection").AsMatrix();
            lightViewVar           = lightShader.GetVariableByName("View").AsMatrix();
            lightViewInverseVar    = lightShader.GetVariableByName("ViewInverse").AsMatrix();
            lightViewportWidthVar  = lightShader.GetVariableByName("ViewportWidth").AsScalar();
            lightViewportHeightVar = lightShader.GetVariableByName("ViewportHeight").AsScalar();
            lightEyePositionVar    = lightShader.GetVariableByName("EyePosition").AsVector();
            lightViewParametersVar = lightShader.GetVariableByName("ViewParameters").AsVector();

            var elements = new InputElement[]
            {
                new InputElement("POSITION", 0, Format.R32G32B32_Float, 0, 0, InputClassification.PerVertexData, 0),
            };

            lightVolumeInputLayout = new InputLayout(Device, lightShader.GetTechniqueByIndex(0).GetPassByName("Light").Description.Signature, elements);

            pointLightVolumeVertices = Light.CreatePointLightVolume(out pointLightVolumeIndices);
            var vertexBufferDesc = new BufferDescription
            {
                SizeInBytes = Vector3.SizeInBytes * pointLightVolumeVertices.Length,
                Usage       = ResourceUsage.Default,
                BindFlags   = BindFlags.VertexBuffer,
            };

            using (var data = new DataStream(vertexBufferDesc.SizeInBytes, false, true))
            {
                data.WriteRange(pointLightVolumeVertices);
                data.Position = 0;
                pointLightVolumeVertexBuffer = new Buffer(Device, data, vertexBufferDesc);
            }
            pointLightVolumeVertexBufferBinding = new VertexBufferBinding(pointLightVolumeVertexBuffer, 12, 0);

            var indexBufferDesc = new BufferDescription
            {
                SizeInBytes = sizeof(uint) * pointLightVolumeIndices.Length,
                Usage       = ResourceUsage.Default,
                BindFlags   = BindFlags.IndexBuffer
            };

            using (var data = new DataStream(indexBufferDesc.SizeInBytes, false, true))
            {
                data.WriteRange(pointLightVolumeIndices);
                data.Position = 0;
                pointLightVolumeIndexBuffer = new Buffer(Device, data, indexBufferDesc);
            }

            lightDepthBufferVar  = lightShader.GetVariableByName("depthBuffer").AsShaderResource();
            lightNormalBufferVar = lightShader.GetVariableByName("normalBuffer").AsShaderResource();

            lights.Add(new Light(pointLightPosition, 60, new Vector4(1, 0.95f, 0.9f, 1)));
            //lights.Add(new Light(pointLightPosition, 60, new Vector4(0, 0, 1, 1)));
            //lights.Add(new Light(new Vector3(-10, 10, 10), 30, new Vector4(1, 0, 0, 1)));
            //lights.Add(new Light(new Vector3(10, 5, -10), 20, new Vector4(0, 1, 0, 1)));
            //lights.Add(new Light(new Vector3(-10, 5, -10), 20, new Vector4(1, 0, 1, 1)));


            info         = new InfoText(Device, 256, 256);
            _meshFactory = new MeshFactory(this);
            MeshFactory  = _meshFactory;

            CreateBuffers();
            GraphicsLibraryManager.LibraryStarted();
        }