コード例 #1
0
ファイル: VolumeRenderer.cs プロジェクト: ishkang/Gorgon
        /// <summary>Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources.</summary>
        public void Dispose()
        {
            for (int i = 0; i < _volumeRtSections.Length; ++i)
            {
                _volumeSections[i]?.Dispose();
                _volumeRtSections[i]?.Dispose();
            }
            _textureView = null;

            _cube?.Dispose();
            _volumeScaleFactor?.Dispose();
            _volumeRayParams?.Dispose();
            _cubeTransform?.Dispose();
            _cubePosShader?.Dispose();
            _cubeDirShader?.Dispose();
            _cubeVs?.Dispose();
            _inputLayout?.Dispose();

            _cubeTransform     = null;
            _inputLayout       = null;
            _cube              = null;
            _volumeScaleFactor = null;
            _volumeRayParams   = null;
            _cubePosShader     = null;
            _cubeDirShader     = null;
            _cubeVs            = null;
        }
コード例 #2
0
        /// <summary>
        /// Initializes a new instance of the <see cref="Cube"/> class.
        /// </summary>
        /// <param name="graphics">The graphics object used to create the buffers needed by this object.</param>
        /// <param name="inputLayout">The input layout describing how a vertex is laid out.</param>
        public Cube(GorgonGraphics graphics, GorgonInputLayout inputLayout)
        {
            CubeVertex[] vertices =
            {
                new CubeVertex(new DX.Vector3(-0.5f,  0.5f, -0.5f), new DX.Vector3(0,       0, 0)),
                new CubeVertex(new DX.Vector3(0.5f,   0.5f, -0.5f), new DX.Vector3(1.0f, 1.0f, 0)),
                new CubeVertex(new DX.Vector3(0.5f,  -0.5f, -0.5f), new DX.Vector3(0.0f, 1.0f, 0)),
                new CubeVertex(new DX.Vector3(-0.5f, -0.5f, -0.5f), new DX.Vector3(1.0f, 0.0f, 0)),

                new CubeVertex(new DX.Vector3(-0.5f,  0.5f,  0.5f), new DX.Vector3(0,       0, 0)),
                new CubeVertex(new DX.Vector3(0.5f,   0.5f,  0.5f), new DX.Vector3(1.0f, 1.0f, 0)),
                new CubeVertex(new DX.Vector3(0.5f,  -0.5f,  0.5f), new DX.Vector3(0.0f, 1.0f, 0)),
                new CubeVertex(new DX.Vector3(-0.5f, -0.5f,  0.5f), new DX.Vector3(1.0f, 0.0f, 0)),
            };

            ushort[] indices =
            {
                // Front face.
                0, 1, 2,
                2, 3, 0,
                // Back face.
                5, 4, 6,
                4, 7, 6,
                // Left face.
                4, 0, 3,
                3, 7, 4,
                // Right face.
                1, 5, 6,
                6, 2, 1,
                // Top face
                4, 5, 1,
                1, 0, 4,
                // Bottom face
                2, 6, 7,
                7, 3, 2
            };

            // Create our index buffer and vertex buffer and populate with our cube data.
            using (var indexPtr = GorgonNativeBuffer <ushort> .Pin(indices))
                using (var vertexPtr = GorgonNativeBuffer <CubeVertex> .Pin(vertices))
                {
                    IndexBuffer = new GorgonIndexBuffer(graphics,
                                                        new GorgonIndexBufferInfo("Volume Index Buffer")
                    {
                        Usage           = ResourceUsage.Immutable,
                        IndexCount      = indices.Length,
                        Use16BitIndices = true
                    },
                                                        indexPtr);

                    VertexBuffer = new GorgonVertexBufferBindings(inputLayout)
                    {
                        [0] = GorgonVertexBufferBinding.CreateVertexBuffer(graphics,
                                                                           vertices.Length,
                                                                           ResourceUsage.Immutable,
                                                                           initialData: vertexPtr,
                                                                           bufferName: "Volume Vertex Buffer")
                    };
                }
        }
コード例 #3
0
ファイル: DrawCallFactory.cs プロジェクト: ishkang/Gorgon
 /// <summary>
 /// Initializes a new instance of the <see cref="DrawCallFactory"/> class.
 /// </summary>
 /// <param name="graphics">The graphics interface to use when creating states.</param>
 /// <param name="defaultTexture">The default texture to use as a fallback when no texture is passed by renderable.</param>
 /// <param name="inputLayout">The input layout defining a vertex type.</param>
 public DrawCallFactory(GorgonGraphics graphics, GorgonTexture2DView defaultTexture, GorgonInputLayout inputLayout)
 {
     _inputLayout        = inputLayout;
     _drawIndexAllocator = new GorgonDrawCallPoolAllocator <GorgonDrawIndexCall>(128);
     _drawAllocator      = new GorgonDrawCallPoolAllocator <GorgonDrawCall>(128);
     _drawIndexBuilder   = new GorgonDrawIndexCallBuilder();
     _drawBuilder        = new GorgonDrawCallBuilder();
     _stateBuilder       = new GorgonPipelineStateBuilder(graphics);
     _defaultTexture     = defaultTexture;
 }
コード例 #4
0
ファイル: PlanetLayer.cs プロジェクト: ishkang/Gorgon
        /// <summary>
        /// Function to load the resources for the layer.
        /// </summary>
        public override void LoadResources()
        {
            _drawCalls = new List <GorgonDrawIndexCall>();
            BuildConstantBuffers();

            for (int i = 0; i < Planets.Count; ++i)
            {
                Planet planet = Planets[i];

                for (int j = 0; j < planet.Layers.Count; ++j)
                {
                    PlanetaryLayer layer = planet.Layers[j];

                    GorgonVertexShader vertexShader = _resources.VertexShaders[layer.Mesh.Material.VertexShader];
                    GorgonPixelShader  pixelShader  = _resources.PixelShaders[layer.Mesh.Material.PixelShader];

                    // Create our vertex layout now.
                    if (_vertexLayout == null)
                    {
                        _vertexLayout = _vertexLayout = GorgonInputLayout.CreateUsingType <Vertex3D>(_graphics, vertexShader);
                    }

                    // Set up a pipeline state for the mesh.
                    GorgonPipelineState pipelineState = _stateBuilder.Clear()
                                                        .PixelShader(pixelShader)
                                                        .VertexShader(vertexShader)
                                                        .BlendState(layer.Mesh.Material.BlendState)
                                                        .PrimitiveType(PrimitiveType.TriangleList)
                                                        .Build();
                    _drawCallBuilder.Clear()
                    .PipelineState(pipelineState)
                    .IndexBuffer(layer.Mesh.IndexBuffer, 0, layer.Mesh.IndexCount)
                    .VertexBuffer(_vertexLayout, new GorgonVertexBufferBinding(layer.Mesh.VertexBuffer, Vertex3D.Size))
                    .ConstantBuffer(ShaderType.Vertex, _viewProjectionBuffer)
                    .ConstantBuffer(ShaderType.Vertex, _worldBuffer, 1)
                    .ConstantBuffer(ShaderType.Pixel, _cameraBuffer)
                    .ConstantBuffer(ShaderType.Pixel, _lightBuffer, 1)
                    .ConstantBuffer(ShaderType.Pixel, _materialBuffer, 2);

                    (int startTexture, int textureCount) = layer.Mesh.Material.Textures.GetDirtyItems();

                    for (int k = startTexture; k < startTexture + textureCount; ++k)
                    {
                        GorgonTexture2DView texture = _resources.Textures[layer.Mesh.Material.Textures[k]];
                        _drawCallBuilder.ShaderResource(ShaderType.Pixel, texture, k);
                        // We should have this in the material, but since we know what we've got here, this will be fine.
                        _drawCallBuilder.SamplerState(ShaderType.Pixel, GorgonSamplerState.Wrapping, k);
                    }

                    _drawCalls.Add(_drawCallBuilder.Build());
                }
            }

            UpdateLightTransforms();
        }
コード例 #5
0
        /// <summary>
        /// Function to save the state information to this object.
        /// </summary>
        private void Save()
        {
            _targets               = _graphics.Output.GetRenderTargets();
            _uavs                  = _graphics.Output.GetUnorderedAccessViews();
            _indexBuffer           = _graphics.Input.IndexBuffer;
            _vertexBuffer          = _graphics.Input.VertexBuffers[0];
            _inputLayout           = _graphics.Input.Layout;
            _primitiveType         = _graphics.Input.PrimitiveType;
            _pixelShader           = _graphics.Shaders.PixelShader.Current;
            _vertexShader          = _graphics.Shaders.VertexShader.Current;
            _blendStates           = _graphics.Output.BlendingState.States;
            _blendFactor           = _graphics.Output.BlendingState.BlendFactor;
            _blendSampleMask       = _graphics.Output.BlendingState.BlendSampleMask;
            _rasterStates          = _graphics.Rasterizer.States;
            _samplerState          = _graphics.Shaders.PixelShader.TextureSamplers[0];
            _resource              = _graphics.Shaders.PixelShader.Resources[0];
            _depthStencilState     = _graphics.Output.DepthStencilState.States;
            _depthStencilReference = _graphics.Output.DepthStencilState.StencilReference;
            _rasterStates.IsScissorTestingEnabled = false;
            _depthStencil = _graphics.Output.DepthStencilView;
            _viewports    = _graphics.Rasterizer.GetViewports();
            _scissorTests = _graphics.Rasterizer.GetScissorRectangles();
            _alphaTest    = new Gorgon2DAlphaTest(Gorgon2D.IsAlphaTestEnabled, GorgonRangeF.Empty);

            _vsConstantBuffers = new Dictionary <int, GorgonConstantBuffer>();
            _psConstantBuffers = new Dictionary <int, GorgonConstantBuffer>();

            // Only store the constant buffers that we were using.
            // We need to store all the constant buffers because the effects
            // make use of multiple constant slots.  Unlike the resource views,
            // where we know that we're only using the first item (all bets are
            // off if a user decides to use another resource view slot), there's no
            // guarantee that we'll be only using 1 or 2 constant buffer slots.
            for (int i = 0; i < _graphics.Shaders.VertexShader.ConstantBuffers.Count; i++)
            {
                if (_graphics.Shaders.VertexShader.ConstantBuffers[i] != null)
                {
                    _vsConstantBuffers[i] = _graphics.Shaders.VertexShader.ConstantBuffers[i];
                }
            }

            for (int i = 0; i < _graphics.Shaders.PixelShader.ConstantBuffers.Count; i++)
            {
                if (_graphics.Shaders.PixelShader.ConstantBuffers[i] != null)
                {
                    _psConstantBuffers[i] = _graphics.Shaders.PixelShader.ConstantBuffers[i];
                }
            }
        }
コード例 #6
0
ファイル: Plane.cs プロジェクト: ishkang/Gorgon
        /// <summary>
        /// Initializes a new instance of the <see cref="Plane" /> class.
        /// </summary>
        /// <param name="graphics">The graphics interface used to create the buffers for this object.</param>
        /// <param name="inputLayout">The input layout for the vertices in this mesh.</param>
        /// <param name="size">The width and height of the plane.</param>
        /// <param name="textureCoordinates">Texture coordinates.</param>
        public Plane(GorgonGraphics graphics, GorgonInputLayout inputLayout, DX.Vector2 size, DX.RectangleF textureCoordinates)
            : base(inputLayout)
        {
            Size = size;

            // Create our vertices.
            Vertices = new[]
            {
                new BoingerVertex(new DX.Vector3(-size.X, size.Y, 0.0f), textureCoordinates.Location),
                new BoingerVertex(new DX.Vector3(size.X, size.Y, 0.0f), new DX.Vector2(textureCoordinates.Right, textureCoordinates.Top)),
                new BoingerVertex(new DX.Vector3(-size.X, -size.Y, 0.0f), new DX.Vector2(textureCoordinates.Left, textureCoordinates.Bottom)),
                new BoingerVertex(new DX.Vector3(size.X, -size.Y, 0.0f), new DX.Vector2(textureCoordinates.Right, textureCoordinates.Bottom))
            };

            // Create our indices.
            Indices = new ushort[]
            {
                0,
                1,
                2,
                2,
                1,
                3
            };

            // Copy the above vertex/index data into a vertex and index buffer so we can render our plane.
            using (var vertexPtr = GorgonNativeBuffer <BoingerVertex> .Pin(Vertices))
                using (var indexPtr = GorgonNativeBuffer <ushort> .Pin(Indices))
                {
                    VertexBufferBindings[0] = GorgonVertexBufferBinding.CreateVertexBuffer(graphics,
                                                                                           new GorgonVertexBufferInfo("Plane Vertex Buffer")
                    {
                        SizeInBytes =
                            Vertices.Length * BoingerVertex.Size,
                        Usage = ResourceUsage.Immutable
                    },
                                                                                           vertexPtr);

                    IndexBuffer = new GorgonIndexBuffer(graphics,
                                                        new GorgonIndexBufferInfo("Plane Index Buffer")
                    {
                        Usage           = ResourceUsage.Immutable,
                        IndexCount      = Indices.Length,
                        Use16BitIndices = true
                    },
                                                        indexPtr);
                }
        }
コード例 #7
0
        /// <summary>
        /// Function to create a draw call based on a mesh.
        /// </summary>
        /// <param name="mesh">The mesh to evaluate.</param>
        private void AddDrawCall(Mesh mesh)
        {
            // Find out which shaders are used by the mesh and retrieve them from the cache.
            if (!ShaderCache.TryGetValue(mesh.Material.VertexShader, out GorgonShader shader))
            {
                return;
            }

            var vertexShader = (GorgonVertexShader)shader;

            if (!ShaderCache.TryGetValue(mesh.Material.PixelShader, out shader))
            {
                return;
            }

            // Not an ideal place for this, but since we don't know when a vertex shader will be added to our renderer, and we require a vertex shader for our
            // input layout, then this will have to suffice.  In a real renderer, we'd cache the vertex inputs per shader and just look it up because the type
            // of vertex may not be what we expect. In this case, we *know* that we're using Vertex3D and no other vertex type, so we're 100% safe doing it
            // here in this example.
            if ((_vertexLayout == null) && (vertexShader != null))
            {
                _vertexLayout = GorgonInputLayout.CreateUsingType <Vertex3D>(_graphics, vertexShader);
            }

            var pixelShader = (GorgonPixelShader)shader;

            GorgonPipelineState pipelineState = _stateBuilder.Clear()
                                                .DepthStencilState(mesh.IsDepthWriteEnabled
                                                                                    ? GorgonDepthStencilState.DepthEnabled
                                                                                    : GorgonDepthStencilState.DepthEnabledNoWrite)
                                                .PixelShader(pixelShader)
                                                .VertexShader(vertexShader)
                                                .BlendState(mesh.Material.BlendState)
                                                .PrimitiveType(mesh.PrimitiveType)
                                                .Build();

            _drawBuilder.Clear()
            .PipelineState(pipelineState)
            .IndexBuffer(mesh.IndexBuffer, 0, mesh.IndexCount)
            .VertexBuffer(_vertexLayout, new GorgonVertexBufferBinding(mesh.VertexBuffer, Vertex3D.Size))
            .ConstantBuffer(ShaderType.Vertex, _viewProjectionBuffer)
            .ConstantBuffer(ShaderType.Vertex, _worldBuffer, 1)
            .ConstantBuffer(ShaderType.Pixel, _cameraBuffer)
            .ConstantBuffer(ShaderType.Pixel, _lightBuffer, 1)
            .ConstantBuffer(ShaderType.Pixel, _materialBuffer, 2);

            ref readonly (int Start, int Count)textures = ref mesh.Material.Textures.GetDirtyItems();
コード例 #8
0
ファイル: DrawCallFactory.cs プロジェクト: ishkang/Gorgon
 /// <summary>
 /// Function to retrieve a draw indexed call from the pool and,  initialize it.
 /// </summary>
 /// <param name="renderable">The renderable to evaluate.</param>
 /// <param name="batchState">The current global state for the batch.</param>
 /// <param name="indexBuffer">The index buffer to use when creating the draw call.</param>
 /// <param name="vertexBuffer">The vertex buffer binding to use when creating the draw call.</param>
 /// <param name="layout">The vertex input layout.</param>
 /// <returns>The draw call.</returns>
 public GorgonDrawIndexCall GetDrawIndexCall(BatchRenderable renderable, Gorgon2DBatchState batchState, GorgonIndexBuffer indexBuffer, GorgonVertexBufferBinding vertexBuffer, GorgonInputLayout layout)
 {
     SetCommonStates(_drawIndexBuilder, renderable, batchState, null);
     return(_drawIndexBuilder.VertexBuffer(layout, vertexBuffer)
            .IndexBuffer(indexBuffer)
            .Build(_drawIndexAllocator));
 }
コード例 #9
0
ファイル: TextureBlitter.cs プロジェクト: ishkang/Gorgon
        /// <summary>
        /// Function to initialize the blitter.
        /// </summary>
        public void Initialize()
        {
            try
            {
                // We've been initialized, so leave.
                if ((_vertexShader != null) || (Interlocked.Increment(ref _initializedFlag) > 1))
                {
                    // Trap other threads until we're done initializing and then release them.
                    while ((_vertexShader == null) && (_initializedFlag > 0))
                    {
                        var wait = new SpinWait();
                        wait.SpinOnce();
                    }

                    return;
                }


                _vertexShader = GorgonShaderFactory.Compile <GorgonVertexShader>(_graphics,
                                                                                 Resources.GraphicsShaders,
                                                                                 "GorgonBltVertexShader",
                                                                                 GorgonGraphics.IsDebugEnabled);
                _pixelShader = GorgonShaderFactory.Compile <GorgonPixelShader>(_graphics,
                                                                               Resources.GraphicsShaders,
                                                                               "GorgonBltPixelShader",
                                                                               GorgonGraphics.IsDebugEnabled);

                _inputLayout = GorgonInputLayout.CreateUsingType <BltVertex>(_graphics, _vertexShader);

                _vertexBufferBindings = new GorgonVertexBufferBindings(_inputLayout)
                {
                    [0] = GorgonVertexBufferBinding.CreateVertexBuffer <BltVertex>(_graphics,
                                                                                   4,
                                                                                   ResourceUsage.Dynamic,
                                                                                   bufferName: "Gorgon Blitter Vertex Buffer")
                };

                _wvpBuffer = GorgonConstantBufferView.CreateConstantBuffer(_graphics,
                                                                           new GorgonConstantBufferInfo("Gorgon Blitter WVP Buffer")
                {
                    Usage       = ResourceUsage.Dynamic,
                    SizeInBytes = DX.Matrix.SizeInBytes
                });

                // Finish initalizing the draw call.
                _pipelineState = _pipeStateBuilder.VertexShader(_vertexShader)
                                 .BlendState(GorgonBlendState.NoBlending)
                                 .DepthStencilState(GorgonDepthStencilState.Default)
                                 .PrimitiveType(PrimitiveType.TriangleStrip)
                                 .RasterState(GorgonRasterState.Default)
                                 .PixelShader(_pixelShader)
                                 .Build();

                _drawCallBuilder.VertexBuffers(_inputLayout, _vertexBufferBindings)
                .VertexRange(0, 4)
                .SamplerState(ShaderType.Pixel, GorgonSamplerState.Default)
                .PipelineState(_pipelineState)
                .ConstantBuffer(ShaderType.Vertex, _wvpBuffer);


                _defaultTexture = Resources.White_2x2.ToTexture2D(_graphics,
                                                                  new GorgonTexture2DLoadOptions
                {
                    Name    = "Gorgon_Default_White_Texture",
                    Usage   = ResourceUsage.Immutable,
                    Binding = TextureBinding.ShaderResource
                }).GetShaderResourceView();
            }
            finally
            {
                Interlocked.Decrement(ref _initializedFlag);
            }
        }
コード例 #10
0
        /// <summary>
        /// Function to initialize the GPU resource objects.
        /// </summary>
        private static void InitializeGpuResources()
        {
            _graphics = CreateGraphicsInterface();

            // If we couldn't create the graphics interface, then leave.
            if (_graphics == null)
            {
                return;
            }

            // Create a 1280x800 window with a depth buffer.
            // We can modify the resolution in the config file for the application, but like other Gorgon examples, the default is 1280x800.
            _swap = new GorgonSwapChain(_graphics,
                                        _mainForm,
                                        new GorgonSwapChainInfo("Main")
            {
                // Set up for 32 bit RGBA normalized display.
                Format = BufferFormat.R8G8B8A8_UNorm,
                Width  = Settings.Default.Resolution.Width,
                Height = Settings.Default.Resolution.Height
            });

            // Build the depth buffer for our swap chain.
            BuildDepthBuffer(_swap.Width, _swap.Height);


            if (!Settings.Default.IsWindowed)
            {
                // Get the output for the main window.
                var currentScreen             = Screen.FromControl(_mainForm);
                IGorgonVideoOutputInfo output = _graphics.VideoAdapter.Outputs[currentScreen.DeviceName];

                // If we've asked for full screen mode, then locate the correct video mode and set us up.
                _selectedVideoMode = new GorgonVideoMode(Settings.Default.Resolution.Width, Settings.Default.Resolution.Height, BufferFormat.R8G8B8A8_UNorm);
                _swap.EnterFullScreen(in _selectedVideoMode, output);
            }

            // Handle resizing because the projection matrix and depth buffer needs to be updated to reflect the new view size.
            _swap.BeforeSwapChainResized += Swap_BeforeResized;
            _swap.AfterSwapChainResized  += Swap_AfterResized;

            // Set the current render target output so we can see something.
            _graphics.SetRenderTarget(_swap.RenderTargetView, _depthBuffer);

            // Create our shaders.
            // Our vertex shader.  This is a simple shader, it just processes a vertex by multiplying it against
            // the world/view/projection matrix and spits it back out.
            _vertexShader = GorgonShaderFactory.Compile <GorgonVertexShader>(_graphics, Resources.Shader, "BoingerVS");

            // Our main pixel shader.  This is a very simple shader, it just reads a texture and spits it back out.  Has no
            // diffuse capability.
            _pixelShader = GorgonShaderFactory.Compile <GorgonPixelShader>(_graphics, Resources.Shader, "BoingerPS");

            // Create the vertex input layout.
            // We need to create a layout for our vertex type because the shader won't know how to interpret the data we're sending it otherwise.
            // This is why we need a vertex shader before we even create the layout.
            _inputLayout = GorgonInputLayout.CreateUsingType <BoingerVertex>(_graphics, _vertexShader);

            // Resources are stored as System.Drawing.Bitmap files, so we need to convert into an IGorgonImage so we can upload it to a texture.
            // We also will generate mip-map levels for this image so that scaling the texture will look better.
            using (IGorgonImage image = Resources.Texture.ToGorgonImage())
            {
                _texture = image.ToTexture2D(_graphics,
                                             new GorgonTexture2DLoadOptions
                {
                    Usage = ResourceUsage.Immutable,
                    Name  = "Texture"
                })
                           .GetShaderResourceView();
            }

            // Create our constant buffer.
            // Our constant buffers are how we send data to our shaders.  This one in particular will be responsible for sending our world/view/projection matrix
            // to the vertex shader.
            _wvpBuffer = GorgonConstantBufferView.CreateConstantBuffer(_graphics,
                                                                       new GorgonConstantBufferInfo("WVPBuffer")
            {
                Usage       = ResourceUsage.Dynamic,
                SizeInBytes = DX.Matrix.SizeInBytes
            });
            // This one will hold our material information.
            _materialBuffer = GorgonConstantBufferView.CreateConstantBuffer(_graphics,
                                                                            new GorgonConstantBufferInfo("MaterialBuffer")
            {
                Usage       = ResourceUsage.Dynamic,
                SizeInBytes = Unsafe.SizeOf <GorgonColor>()
            });
            GorgonColor defaultMaterialColor = GorgonColor.White;

            _materialBuffer.Buffer.SetData(ref defaultMaterialColor);

            GorgonExample.LoadResources(_graphics);
        }
コード例 #11
0
ファイル: Program.cs プロジェクト: tmp7701/Gorgon
        /// <summary>
        /// Function to initialize the application.
        /// </summary>
        private static void Initialize()
        {
            var depthFormat = BufferFormat.D24_UIntNormal_S8_UInt;                              // Depth buffer format.

            // Create our form.
            _mainForm = new formMain();

            // Add a keybinding to switch to full screen or windowed.
            _mainForm.KeyDown += _mainForm_KeyDown;

            // Create the main graphics interface.
            Graphics = new GorgonGraphics();

            // Validate depth buffer for this device.
            // Odds are good that if this fails, you should probably invest in a
            // better video card.  Preferably something created after 2005.
            if (!Graphics.VideoDevice.SupportsDepthFormat(depthFormat))
            {
                depthFormat = BufferFormat.D16_UIntNormal;

                if (Graphics.VideoDevice.SupportsDepthFormat(depthFormat))
                {
                    return;
                }

                GorgonDialogs.ErrorBox(_mainForm, "Video device does not support a 24 or 16 bit depth buffer.");
                return;
            }

            // Create a 1280x800 window with a depth buffer.
            // We can modify the resolution in the config file for the application, but
            // like other Gorgon examples, the default is 1280x800.
            _swap = Graphics.Output.CreateSwapChain("Main", new GorgonSwapChainSettings
            {
                Window             = _mainForm,                                         // Assign to our form.
                Format             = BufferFormat.R8G8B8A8_UIntNormal,                  // Set up for 32 bit RGBA normalized display.
                Size               = Settings.Default.Resolution,                       // Get the resolution from the config file.
                DepthStencilFormat = depthFormat,                                       // Get our depth format.
                IsWindowed         = Settings.Default.IsWindowed                        // Set up for windowed or full screen (depending on config file).
            });

            // Center on the primary monitor.
            // This is necessary because we already created the window, so it'll be off center at this point.
            _mainForm.Location = new Point(Screen.PrimaryScreen.WorkingArea.Width / 2 - _mainForm.Width / 2,
                                           Screen.PrimaryScreen.WorkingArea.Height / 2 - _mainForm.Height / 2);

            // Handle any resizing.
            // This is here because the base graphics library will NOT handle state loss due to resizing.
            // This is up to the developer to handle.
            _swap.AfterSwapChainResized += _swap_Resized;

            // Create the 2D interface for our text.
            _2D = Graphics.Output.Create2DRenderer(_swap);

            // Create our shaders.
            // Our vertex shader.  This is a simple shader, it just processes a vertex by multiplying it against
            // the world/view/projection matrix and spits it back out.
            _vertexShader = Graphics.Shaders.CreateShader <GorgonVertexShader>("VertexShader", "BoingerVS", Resources.Shader);
            // Our main pixel shader.  This is a very simple shader, it just reads a texture and spits it back out.  Has no
            // diffuse capability.
            _pixelShader = Graphics.Shaders.CreateShader <GorgonPixelShader>("PixelShader", "BoingerPS", Resources.Shader);
            // Our shadow shader for our ball "shadow".  This is hard coded to send back black (R:0, G:0, B:0) at 50% opacity (A: 0.5).
            _pixelShaderShadow = Graphics.Shaders.CreateShader <GorgonPixelShader>("ShadowShader", "BoingerShadowPS", Resources.Shader);

            // Create the vertex input layout.
            // We need to create a layout for our vertex type because the shader won't know
            // how to interpret the data we're sending it otherwise.  This is why we need a
            // vertex shader before we even create the layout.
            _inputLayout = Graphics.Input.CreateInputLayout("InputLayout", typeof(BoingerVertex), _vertexShader);

            // Create the view port.
            // This just tells the renderer how big our display is.
            var view = new GorgonViewport(0, 0, _mainForm.ClientSize.Width, _mainForm.ClientSize.Height, 0.0f, 1.0f);

            // Load our textures from the resources.
            // This contains our textures for the walls and ball.
            _texture = Graphics.Textures.CreateTexture <GorgonTexture2D>("PlaneTexture", Resources.Texture);

            // Set up our view matrix.
            // Move the camera (view matrix) back 2.2 units.  This will give us enough room to see what's
            // going on.
            Matrix.Translation(0, 0, 2.2f, out _viewMatrix);

            // Set up our projection matrix.
            // This matrix is probably the cause of almost EVERY problem you'll ever run into in 3D programming.
            // Basically we're telling the renderer that we want to have a vertical FOV of 75 degrees, with the aspect ratio
            // based on our form width and height.  The final values indicate how to distribute Z values across depth (tip:
            // it's not linear).
            _projMatrix = Matrix.PerspectiveFovLH((75.0f).Radians(), _mainForm.Width / (float)_mainForm.Height, 0.125f, 500.0f);

            // Create our constant buffer and backing store.
            // Our constant buffers are how we send data to our shaders.  This one in particular will be responsible
            // for sending our world/view/projection matrix to the vertex shader.  The stream we're creating after
            // the constant buffer is our system memory store for the data.  Basically we write to the system
            // memory and then upload that data to the video card.  This is very different from how things used to
            // work, but allows a lot more flexibility.
            _wvpBuffer = Graphics.Buffers.CreateConstantBuffer("WVPBuffer", new GorgonConstantBufferSettings
            {
                SizeInBytes = Matrix.SizeInBytes
            });
            _wvpBufferStream = new GorgonDataStream(_wvpBuffer.SizeInBytes);

            // Create our planes.
            // Here's where we create the 2 planes for our rear wall and floor.  We set the texture size to texel units
            // because that's how the video card expects them.  However, it's a little hard to eyeball 0.67798223f by looking
            // at the texture image display, so we use the ToTexel function to determine our texel size.
            var textureSize = _texture.ToTexel(new Vector2(500, 500));

            _planes = new[] {
                new Plane(new Vector2(3.5f), new RectangleF(Vector2.Zero, textureSize)),
                new Plane(new Vector2(3.5f), new RectangleF(Vector2.Zero, textureSize))
            };

            // Set up default positions and orientations.
            _planes[0].Position = new Vector3(0, 0, 3.0f);
            _planes[1].Position = new Vector3(0, -3.5f, 3.5f);
            _planes[1].Rotation = new Vector3(90.0f, 0, 0);

            // Create our sphere.
            // Again, here we're using texels to align the texture coordinates to the other image
            // packed into the texture (atlasing).
            var textureOffset = _texture.ToTexel(new Vector2(516, 0));

            // This is to scale our texture coordinates because the actual image is much smaller
            // (256x256) than the full texture (1024x512).
            textureSize.X = 0.245f;
            textureSize.Y = 0.5f;
            // Give the sphere a place to live.
            _sphere = new Sphere(1.0f, textureOffset, textureSize)
            {
                Position = new Vector3(2.2f, 1.5f, 2.5f)
            };


            // Bind our objects to the pipeline and set default states.
            // At this point we need to give the graphics card a bunch of things
            // it needs to do its job.

            // Give our current input layout.
            Graphics.Input.Layout = _inputLayout;
            // We're drawing individual triangles for this (and this is usyally the case).
            Graphics.Input.PrimitiveType = PrimitiveType.TriangleList;

            // Bind our current vertex shader and send over our world/view/projection matrix
            // constant buffer.
            Graphics.Shaders.VertexShader.Current            = _vertexShader;
            Graphics.Shaders.VertexShader.ConstantBuffers[0] = _wvpBuffer;

            // Do the same with the pixel shader, only we're binding our texture to it as well.
            // We also need to bind a sampler to the texture because without it, the shader won't
            // know how to interpret the texture data (e.g. how will the shader know if the texture
            // is supposed to be bilinear filtered or point filtered?)
            Graphics.Shaders.PixelShader.Current            = _pixelShader;
            Graphics.Shaders.PixelShader.Resources[0]       = _texture;
            Graphics.Shaders.PixelShader.TextureSamplers[0] = GorgonTextureSamplerStates.LinearFilter;

            // Turn on alpha blending.
            Graphics.Output.BlendingState.States = GorgonBlendStates.ModulatedBlending;

            // Turn on depth writing.
            // This is our depth writing state.  When this is on, all polygon data sent to the card
            // will write to our depth buffer.  Normally we want this, but for translucent objects, it's
            // problematic....
            _depth = new GorgonDepthStencilStates
            {
                DepthComparison     = ComparisonOperator.LessEqual,
                IsDepthEnabled      = true,
                IsDepthWriteEnabled = true,
                IsStencilEnabled    = false
            };

            // Turn off depth writing.
            // So, we copy the depth state and turn off depth writing so that translucent objects
            // won't write to the depth buffer but can still read it.
            _noDepth = _depth;
            _noDepth.IsDepthWriteEnabled             = false;
            Graphics.Output.DepthStencilState.States = _depth;

            // Bind our swap chain and set up the default rasterizer states.
            Graphics.Output.SetRenderTarget(_swap, _swap.DepthStencilBuffer);
            Graphics.Rasterizer.States = GorgonRasterizerStates.CullBackFace;
            Graphics.Rasterizer.SetViewport(view);

            // I know, there's a lot in here.  Thing is, if this were Direct 3D 11 code, it'd probably MUCH
            // more code and that's even before creating our planes and sphere.
        }
コード例 #12
0
        public void Init()
        {
            _form = new TestForm
            {
                ShowTestPanel = true,
                ClientSize    = new Size(1280, 800)
            };
            _form.WindowState = FormWindowState.Minimized;
            _form.Show();
            _form.WindowState = FormWindowState.Normal;

            _graphics = new GorgonGraphics();
            _swap     = _graphics.Output.CreateSwapChain("Screen", new GorgonSwapChainSettings()
            {
                Window             = _form.panelDisplay,
                DepthStencilFormat = BufferFormat.D24_UIntNormal_S8_UInt
            });

            _swap.AfterSwapChainResized += (sender, args) =>
            {
                var currentMatrix = new MatrixBuffer();

                _graphics.Rasterizer.SetViewport(_swap.Viewport);
                _aspect = (_swap.Settings.VideoMode.Width) / (float)(_swap.Settings.VideoMode.Height);
                currentMatrix.Projection = Matrix.PerspectiveFovLH(100.39f.Radians(), _aspect, 0.1f, 1000.0f);
                currentMatrix.View       = Matrix.LookAtLH(new Vector3(0, 0, -0.75f), new Vector3(0, 0, 1.0f), Vector3.UnitY);

                _graphics.Output.SetRenderTarget(_swap, _swap.DepthStencilBuffer);

                pvw = currentMatrix.View * currentMatrix.Projection;
            };

            _swap.AfterStateTransition += (sender, args) =>
            {
                var currentMatrix = new MatrixBuffer();

                _graphics.Rasterizer.SetViewport(_swap.Viewport);
                _aspect = (_swap.Settings.VideoMode.Width) / (float)(_swap.Settings.VideoMode.Height);
                currentMatrix.Projection = Matrix.PerspectiveFovLH(100.39f.Radians(), _aspect, 0.1f, 1000.0f);
                currentMatrix.View       = Matrix.LookAtLH(new Vector3(0, 0, -0.75f), new Vector3(0, 0, 1.0f), Vector3.UnitY);

                _graphics.Output.SetRenderTarget(_swap, _swap.DepthStencilBuffer);

                pvw = currentMatrix.View * currentMatrix.Projection;
            };

            var button = new Button()
            {
                Text     = "3D",
                Location = new Point(90, 3)
            };

            button.Click += (sender, args) =>
            {
                _3d = !_3d;
                Matrix currentMatrix = Matrix.LookAtLH(new Vector3(0, 0, _camPos), new Vector3(0, 0, 1.0f), Vector3.UnitY);
                Matrix projection    = Matrix.PerspectiveFovLH(100.39f.Radians(), _aspect, 0.1f,
                                                               1000.0f);
                pvw = currentMatrix * projection;
            };

            _form.panelInput.Controls.Add(button);

            _sprite = new vertex[Count * 4];

            for (int i = 0; i < Count; i++)
            {
                _balls[i].Scale       = 1.0f;
                _balls[i].ScaleDelta  = (GorgonRandom.RandomSingle() * 1.5f) + 0.25f;
                _balls[i].AlphaBounce = _balls[i].ScaleBouce = false;
                _balls[i].XBounce     = GorgonRandom.RandomInt32(0, 100) > 50;
                _balls[i].YBounce     = GorgonRandom.RandomInt32(0, 100) > 50;
                _balls[i].ZBounce     = GorgonRandom.RandomInt32(0, 100) > 50;
                _balls[i].Velocity    = new Vector3((GorgonRandom.RandomSingle() * 0.5f), (GorgonRandom.RandomSingle() * 0.5f), (GorgonRandom.RandomSingle() * 0.5f));
                _balls[i].Angle       = 0.0f;
                _balls[i].AngleDelta  = 1.0f;
                _balls[i].Color       = new Vector4(1.0f);
                _balls[i].AlphaDelta  = GorgonRandom.RandomSingle() * 0.5f;
                _balls[i].Checkered   = true;          // GorgonRandom.RandomInt32(0, 100) > 50;
                _balls[i].Position    = new Vector3((GorgonRandom.RandomSingle() * 2.0f) - 1.0f, (GorgonRandom.RandomSingle() * 2.0f) - 1.0f, GorgonRandom.RandomSingle());
            }

            _vs = _graphics.Shaders.CreateShader <GorgonVertexShader>("TestVShader", "VS", _shader, null, true);
            _ps = _graphics.Shaders.CreateShader <GorgonPixelShader>("TestPShader", "PS", _shader, null, true);

            _layout = _graphics.Input.CreateInputLayout("Input", typeof(vertex), _vs);

            int vertexSize = _layout.Size;
            int index      = 0;
            var indices    = new int[Count * 6 * sizeof(int)];

            for (int i = 0; i < indices.Length; i += 6)
            {
                indices[i]     = index;
                indices[i + 1] = index + 1;
                indices[i + 2] = index + 2;
                indices[i + 3] = index + 1;
                indices[i + 4] = index + 3;
                indices[i + 5] = index + 2;
                index         += 4;
            }

            _vertices = _graphics.Buffers.CreateVertexBuffer("Vertex", new GorgonBufferSettings()
            {
                SizeInBytes = 4 * vertexSize * Count,
                Usage       = BufferUsage.Dynamic
            });
            _index = _graphics.Buffers.CreateIndexBuffer("Index", indices, BufferUsage.Immutable);

            _texture  = _graphics.Textures.FromFile <GorgonTexture2D>("Balls", @"..\..\..\..\Resources\BallDemo\BallDemo.png", new GorgonCodecPNG());
            _texture2 = _graphics.Textures.FromFile <GorgonTexture2D>("VBBack", @"..\..\..\..\Resources\Images\VBback.jpg", new GorgonCodecJPEG());

            var matrix = new MatrixBuffer();

            _aspect = _swap.Settings.VideoMode.Width / (float)(_swap.Settings.VideoMode.Height);

            matrix.Projection = Matrix.PerspectiveFovLH(100.39f.Radians(), _aspect, 0.1f,
                                                        1000.0f);
            matrix.View      = Matrix.LookAtLH(new Vector3(0, 0, _camPos), new Vector3(0, 0, 1.0f), Vector3.UnitY);
            matrix.Array     = new Vector4[3];
            matrix.Array[0]  = new Vector4(1.0f, 1.0f, 1.0f, 1.0f);
            matrix.Array[1]  = new Vector4(1.0f, 1.0f, 1.0f, 1.0f);
            matrix.Array[2]  = new Vector4(1.0f, 1.0f, 1.0f, 1.0f);
            matrix.valueType = new TEMPGUY
            {
                value2    = matrix.View,
                tempArray = new Vector4[3]
            };

            _depthStateAlpha.IsDepthEnabled      = false;
            _depthStateAlpha.IsDepthWriteEnabled = false;

            _graphics.Input.Layout = _layout;
            _graphics.Shaders.VertexShader.Current = _vs;
            _graphics.Shaders.PixelShader.Current  = _ps;

            _graphics.Shaders.PixelShader.TextureSamplers.SetRange(0, new[] { GorgonTextureSamplerStates.LinearFilter, GorgonTextureSamplerStates.LinearFilter });

            _graphics.Rasterizer.SetViewport(_swap.Viewport);
            _graphics.Output.DepthStencilState.States = _depthStateAlpha;
            _graphics.Output.SetRenderTarget(_swap, _swap.DepthStencilBuffer);
            _graphics.Input.VertexBuffers[0] = new GorgonVertexBufferBinding(_vertices, vertexSize);
            _graphics.Input.IndexBuffer      = _index;
            _graphics.Shaders.PixelShader.Resources.SetRange(0, new GorgonShaderView[] { _texture, _texture2 });
            _graphics.Output.BlendingState.States = GorgonBlendStates.ModulatedBlending;
            pvw = matrix.valueType.value2 * matrix.Projection;

            _tempStream = new GorgonDataStream(_sprite.Length * vertexSize);
        }
コード例 #13
0
        /// <summary>
        /// Function to initialize the application.
        /// </summary>
        private static void Initialize()
        {
            _form = new FormMain();

            _graphics  = new GorgonGraphics();
            _swapChain = _graphics.Output.CreateSwapChain("Swap",
                                                          new GorgonSwapChainSettings
            {
                Window             = _form,
                IsWindowed         = true,
                DepthStencilFormat = BufferFormat.D24_UIntNormal_S8_UInt,
                Format             = BufferFormat.R8G8B8A8_UIntNormal
            });

            _renderer2D = _graphics.Output.Create2DRenderer(_swapChain);

            _font = _graphics.Fonts.CreateFont("AppFont",
                                               new GorgonFontSettings
            {
                FontFamilyName   = "Calibri",
                FontStyle        = FontStyle.Bold,
                FontHeightMode   = FontHeightMode.Pixels,
                AntiAliasingMode = FontAntiAliasMode.AntiAlias,
                OutlineSize      = 1,
                OutlineColor1    = Color.Black,
                Size             = 16.0f
            });

            _vertexShader       = _graphics.Shaders.CreateShader <GorgonVertexShader>("VertexShader", "PrimVS", Resources.Shaders);
            _pixelShader        = _graphics.Shaders.CreateShader <GorgonPixelShader>("PixelShader", "PrimPS", Resources.Shaders);
            _bumpShader         = _graphics.Shaders.CreateShader <GorgonPixelShader>("PixelShader", "PrimPSBump", Resources.Shaders);
            _waterShader        = _graphics.Shaders.CreateShader <GorgonPixelShader>("PixelShader", "PrimPSWaterBump", Resources.Shaders);
            _normalVertexShader = _graphics.Shaders.CreateShader <GorgonVertexShader>("NormalVertexShader", "NormalVS", Resources.Shaders);
            _normalPixelShader  = _graphics.Shaders.CreateShader <GorgonPixelShader>("NormalPixelShader", "NormalPS", Resources.Shaders);
            _vertexLayout       = _graphics.Input.CreateInputLayout("Vertex3D", typeof(Vertex3D), _vertexShader);
            _normalVertexLayout = _graphics.Input.CreateInputLayout("NormalVertex",
                                                                    new[]
            {
                new GorgonInputElement("SV_POSITION",
                                       BufferFormat.R32G32B32A32_Float,
                                       0,
                                       0,
                                       0,
                                       false,
                                       0),
            },
                                                                    _normalVertexShader);

            _graphics.Shaders.VertexShader.Current = _vertexShader;
            _graphics.Shaders.PixelShader.Current  = _pixelShader;
            _graphics.Input.Layout        = _vertexLayout;
            _graphics.Input.PrimitiveType = PrimitiveType.TriangleList;

            _texture       = _graphics.Textures.CreateTexture <GorgonTexture2D>("UVTexture", Resources.UV);
            _earf          = _graphics.Textures.CreateTexture <GorgonTexture2D>("Earf", Resources.earthmap1k);
            _normalMap     = _graphics.Textures.FromMemory <GorgonTexture2D>("RainNRM", Resources.Rain_Height_NRM, new GorgonCodecDDS());
            _normalEarfMap = _graphics.Textures.FromMemory <GorgonTexture2D>("EarfNRM", Resources.earthbump1k_NRM, new GorgonCodecDDS());
            _specMap       = _graphics.Textures.FromMemory <GorgonTexture2D>("RainSPC", Resources.Rain_Height_SPEC, new GorgonCodecDDS());
            _specEarfMap   = _graphics.Textures.CreateTexture <GorgonTexture2D>("EarfSPC", Resources.earthspec1k);
            _cloudMap      = _graphics.Textures.CreateTexture <GorgonTexture2D>("EarfClouds", Resources.earthcloudmap);
            _gorgNrm       = _graphics.Textures.CreateTexture <GorgonTexture2D>("EarfClouds", Resources.normalmap);

            var depth = new GorgonDepthStencilStates
            {
                DepthComparison     = ComparisonOperator.LessEqual,
                IsDepthEnabled      = true,
                IsDepthWriteEnabled = true
            };

            _graphics.Output.DepthStencilState.States = depth;
            _graphics.Output.SetRenderTarget(_swapChain, _swapChain.DepthStencilBuffer);
            _graphics.Rasterizer.States = GorgonRasterizerStates.CullBackFace;
            _graphics.Rasterizer.SetViewport(new GorgonViewport(0, 0, _form.ClientSize.Width, _form.ClientSize.Height, 0, 1.0f));
            _graphics.Shaders.PixelShader.TextureSamplers[0] = GorgonTextureSamplerStates.LinearFilter;

            _wvp = new WorldViewProjection(_graphics);
            _wvp.UpdateProjection(75.0f, _form.ClientSize.Width, _form.ClientSize.Height);

            // When we resize, update the projection and viewport to match our client size.
            _form.Resize += (sender, args) =>
            {
                _graphics.Rasterizer.SetViewport(new GorgonViewport(0, 0, _form.ClientSize.Width, _form.ClientSize.Height, 0, 1.0f));
                _wvp.UpdateProjection(75.0f, _form.ClientSize.Width, _form.ClientSize.Height);
            };

            var     fnU = new Vector3(0.5f, 1.0f, 0);
            var     fnV = new Vector3(1.0f, 1.0f, 0);
            Vector3 faceNormal;

            Vector3.Cross(ref fnU, ref fnV, out faceNormal);
            faceNormal.Normalize();

            _triangle = new Triangle(_graphics, new Vertex3D
            {
                Position = new Vector4(-12.5f, -1.5f, 12.5f, 1),
                Normal   = faceNormal,
                UV       = new Vector2(0, 1.0f)
            }, new Vertex3D
            {
                Position = new Vector4(0, 24.5f, 12.5f, 1),
                Normal   = faceNormal,
                UV       = new Vector2(0.5f, 0.0f)
            }, new Vertex3D
            {
                Position = new Vector4(12.5f, -1.5f, 12.5f, 1),
                Normal   = faceNormal,
                UV       = new Vector2(1.0f, 1.0f)
            })
            {
                Texture  = _texture,
                Position = new Vector3(0, 0, 1.0f)
            };

            _plane = new Plane(_graphics, new Vector2(25.0f, 25.0f), new RectangleF(0, 0, 1.0f, 1.0f), new Vector3(90, 0, 0), 32, 32)
            {
                Position = new Vector3(0, -1.5f, 1.0f),
                Texture  = _texture
            };

            _cube = new Cube(_graphics, new Vector3(1, 1, 1), new RectangleF(0, 0, 1.0f, 1.0f), new Vector3(45.0f, 0, 0), 1, 1)
            {
                Position = new Vector3(0, 0, 1.5f),
                Texture  = _texture
            };

            _sphere = new Sphere(_graphics, 1.0f, new RectangleF(0.0f, 0.0f, 1.0f, 1.0f), Vector3.Zero, 64, 64)
            {
                Position = new Vector3(-2.0f, 1.0f, 0.75f),
                Texture  = _earf
            };

            _clouds = new Sphere(_graphics, 5.175f, new RectangleF(0.0f, 0.0f, 1.0f, 1.0f), Vector3.Zero, 16, 16)
            {
                Position = new Vector3(10, 2, 9.5f),
                Texture  = _cloudMap
            };

            _icoSphere = new IcoSphere(_graphics, 5.0f, new RectangleF(0, 0, 1, 1), Vector3.Zero, 3)
            {
                Rotation = new Vector3(0, -45.0f, 0),
                Position = new Vector3(10, 2, 9.5f),
                Texture  = _earf
            };

            _graphics.Shaders.PixelShader.TextureSamplers[0] = new GorgonTextureSamplerStates
            {
                TextureFilter        = TextureFilter.Linear,
                HorizontalAddressing = TextureAddressing.Wrap,
                VerticalAddressing   = TextureAddressing.Wrap,
                DepthAddressing      = TextureAddressing.Wrap,
                ComparisonFunction   = ComparisonOperator.Always
            };
            _graphics.Shaders.PixelShader.TextureSamplers[2] = new GorgonTextureSamplerStates
            {
                TextureFilter        = TextureFilter.Linear,
                HorizontalAddressing = TextureAddressing.Wrap,
                VerticalAddressing   = TextureAddressing.Wrap,
                DepthAddressing      = TextureAddressing.Wrap,
                ComparisonFunction   = ComparisonOperator.Always
            };

            _graphics.Shaders.PixelShader.TextureSamplers[1] = new GorgonTextureSamplerStates
            {
                TextureFilter        = TextureFilter.Linear,
                HorizontalAddressing = TextureAddressing.Wrap,
                VerticalAddressing   = TextureAddressing.Wrap,
                DepthAddressing      = TextureAddressing.Wrap,
                ComparisonFunction   = ComparisonOperator.Always
            };

            _material = new Material
            {
                UVOffset      = Vector2.Zero,
                SpecularPower = 1.0f
            };

            _materialBuffer = _graphics.Buffers.CreateConstantBuffer("uvOffset", ref _material, BufferUsage.Default);

            _graphics.Shaders.PixelShader.ConstantBuffers[2] = _materialBuffer;

            _light = new Light(_graphics);
            var lightPosition = new Vector3(1.0f, 1.0f, -1.0f);

            _light.UpdateLightPosition(ref lightPosition, 0);
            GorgonColor color = GorgonColor.White;

            _light.UpdateSpecular(ref color, 256.0f, 0);

            lightPosition = new Vector3(-5.0f, 5.0f, 8.0f);
            _light.UpdateLightPosition(ref lightPosition, 1);
            color = Color.Yellow;
            _light.UpdateColor(ref color, 1);
            _light.UpdateSpecular(ref color, 2048.0f, 1);
            _light.UpdateAttenuation(10.0f, 1);

            lightPosition = new Vector3(5.0f, 3.0f, 10.0f);
            _light.UpdateLightPosition(ref lightPosition, 2);
            color = Color.Red;
            _light.UpdateColor(ref color, 2);
            _light.UpdateAttenuation(16.0f, 2);

            var eye    = Vector3.Zero;
            var lookAt = Vector3.UnitZ;
            var up     = Vector3.UnitY;

            _wvp.UpdateViewMatrix(ref eye, ref lookAt, ref up);

            _cameraRotation = Vector2.Zero;

            Gorgon.PlugIns.LoadPlugInAssembly(Application.StartupPath + @"\Gorgon.Input.Raw.dll");

            _input    = GorgonInputFactory.CreateInputFactory("GorgonLibrary.Input.GorgonRawPlugIn");
            _keyboard = _input.CreateKeyboard(_form);
            _mouse    = _input.CreatePointingDevice(_form);

            _keyboard.KeyDown += (sender, args) =>
            {
                if (args.Key == KeyboardKeys.L)
                {
                    _lock = !_lock;
                }
            };

            _mouse.PointingDeviceDown      += Mouse_Down;
            _mouse.PointingDeviceUp        += Mouse_Up;
            _mouse.PointingDeviceWheelMove += (sender, args) =>
            {
                if (args.WheelDelta < 0)
                {
                    _sensitivity -= 0.05f;

                    if (_sensitivity < 0.05f)
                    {
                        _sensitivity = 0.05f;
                    }
                }
                else if (args.WheelDelta > 0)
                {
                    _sensitivity += 0.05f;

                    if (_sensitivity > 2.0f)
                    {
                        _sensitivity = 2.0f;
                    }
                }
            };
            _mouse.PointingDeviceMove += (sender, args) =>
            {
                if (!_mouse.Exclusive)
                {
                    return;
                }

                var delta = args.RelativePosition;
                _cameraRotation.Y      += delta.Y * _sensitivity;                                        //((360.0f * 0.002f) * delta.Y.Sign());
                _cameraRotation.X      += delta.X * _sensitivity;                                        //((360.0f * 0.002f) * delta.X.Sign());
                _mouseStart             = _mouse.Position;
                _mouse.RelativePosition = PointF.Empty;
            };
        }
コード例 #14
0
ファイル: Sphere.cs プロジェクト: hammerforgegames/Gorgon
        /// <summary>
        /// Initializes a new instance of the <see cref="Sphere" /> class.
        /// </summary>
        /// <param name="graphics">The graphics interface used to create the buffers for this object.</param>
        /// <param name="inputLayout">The input layout for the vertices in this mesh.</param>
        /// <param name="radius">Radius of the sphere</param>
        /// <param name="textureOffset">Offset of the texture.</param>
        /// <param name="textureScale">Scale of the texture.</param>
        /// <param name="ringCount">Number of rings in the sphere.</param>
        /// <param name="segmentCount">Number of segments in the sphere.</param>
        public Sphere(GorgonGraphics graphics,
                      GorgonInputLayout inputLayout,
                      float radius,
                      DX.Vector2 textureOffset,
                      DX.Size2F textureScale,
                      int ringCount    = 8,
                      int segmentCount = 16)
            : base(inputLayout)
        {
            ushort index       = 0; // Current index.
            int    vertexIndex = 0; // Current vertex index.
            int    indexIndex  = 0; // Current index array index.

            float deltaRingAngle = ((float)System.Math.PI) / ringCount;
            float deltaSegAngle  = (((float)System.Math.PI) * 2.0f) / segmentCount;

            // Calculate number of vertices and indices required for our sphere.
            int vertexCount = (ringCount + 1) * (segmentCount + 1);
            int indexCount  = 6 * ringCount * (segmentCount + 1);

            Vertices = new BoingerVertex[vertexCount];
            Indices  = new ushort[indexCount];

            Radius = radius;

            // Build our sphere.
            for (int ring = 0; ring <= ringCount; ring++)
            {
                float angle    = deltaRingAngle * ring;
                float ringSin  = angle.Sin();
                var   position = new DX.Vector3(0, angle.Cos() * radius, 0);

                for (int segment = 0; segment <= segmentCount; segment++)
                {
                    var   textureDelta = new DX.Vector2(1.0f - (segment / (float)segmentCount), 1.0f - (ring / (float)ringCount));
                    float segmentAngle = deltaSegAngle * segment;

                    position.X = ringSin * segmentAngle.Sin() * radius;
                    position.Z = ringSin * segmentAngle.Cos() * radius;

                    // Create the vertex.
                    textureDelta.X *= textureScale.Width;
                    textureDelta.Y *= textureScale.Height;
                    textureDelta.X += textureOffset.X;
                    textureDelta.Y += textureOffset.Y;

                    Vertices[vertexIndex++] = new BoingerVertex(
                        position,
                        textureDelta
                        );

                    // Add the indices and skip the last ring.
                    if (ring == ringCount)
                    {
                        continue;
                    }

                    Indices[indexIndex++] = (ushort)(index + segmentCount + 1);
                    Indices[indexIndex++] = index;
                    Indices[indexIndex++] = (ushort)(index + segmentCount);
                    Indices[indexIndex++] = (ushort)(index + segmentCount + 1);
                    Indices[indexIndex++] = (ushort)(index + 1);
                    Indices[indexIndex++] = index;
                    index++;
                }
            }

            // Copy the above vertex/index data into a vertex and index buffer so we can render our sphere.
            using (var indexPtr = GorgonNativeBuffer <ushort> .Pin(Indices))
                using (var vertexPtr = GorgonNativeBuffer <BoingerVertex> .Pin(Vertices))
                {
                    VertexBufferBindings[0] = GorgonVertexBufferBinding.CreateVertexBuffer(graphics,
                                                                                           new GorgonVertexBufferInfo("Sphere Vertex Buffer")
                    {
                        SizeInBytes = Vertices.Length * BoingerVertex.Size,
                        Usage       = ResourceUsage.Immutable
                    },
                                                                                           vertexPtr);
                    IndexBuffer = new GorgonIndexBuffer(graphics,
                                                        new GorgonIndexBufferInfo("Sphere Index Buffer")
                    {
                        Usage      = ResourceUsage.Immutable,
                        IndexCount = Indices.Length
                    },
                                                        indexPtr);
                }
        }
コード例 #15
0
ファイル: VolumeRenderer.cs プロジェクト: ishkang/Gorgon
        /// <summary>
        /// Function used to build the resources required by the volume renderer.
        /// </summary>
        public void CreateResources()
        {
            _cubeVs        = GorgonShaderFactory.Compile <GorgonVertexShader>(_graphics, Resources.VolumeRenderShaders, "VolumeVS", true);
            _cubePosShader = GorgonShaderFactory.Compile <GorgonPixelShader>(_graphics, Resources.VolumeRenderShaders, "VolumePositionPS", true);
            _cubeDirShader = GorgonShaderFactory.Compile <GorgonPixelShader>(_graphics, Resources.VolumeRenderShaders, "VolumeRayCastPS", true);
            _inputLayout   = GorgonInputLayout.CreateUsingType <CubeVertex>(_graphics, _cubeVs);
            _cube          = new Cube(_graphics, _inputLayout);

            _cubeTransform = new GorgonConstantBuffer(_graphics, new GorgonConstantBufferInfo
            {
                SizeInBytes = DX.Matrix.SizeInBytes
            });

            _volumeRayParams = new GorgonConstantBuffer(_graphics, new GorgonConstantBufferInfo
            {
                SizeInBytes = Unsafe.SizeOf <VolumeRayParameters>()
            });

            _volumeScaleFactor = new GorgonConstantBuffer(_graphics, new GorgonConstantBufferInfo
            {
                SizeInBytes = DX.Vector4.SizeInBytes
            });

            // Our camera is never changing, so we only need to define it here.
            DX.Matrix.Translation(0, 0, 1.5f, out _view);
            ResizeRenderRegion();

            UpdateCubeTransform();

            var pipelineBuilder = new GorgonPipelineStateBuilder(_graphics);
            var drawBuilder     = new GorgonDrawIndexCallBuilder();

            pipelineBuilder
            .PixelShader(_cubePosShader)
            .VertexShader(_cubeVs);

            // Position draw calls.
            _cubePosDrawCull = drawBuilder
                               .ConstantBuffer(ShaderType.Vertex, _cubeTransform.GetView())
                               .ConstantBuffer(ShaderType.Vertex, _volumeScaleFactor.GetView(), 1)
                               .PipelineState(pipelineBuilder)
                               .IndexBuffer(_cube.IndexBuffer, indexCount: _cube.IndexBuffer.IndexCount)
                               .VertexBuffer(_inputLayout, _cube.VertexBuffer[0])
                               .Build();

            pipelineBuilder
            .RasterState(GorgonRasterState.CullFrontFace);

            _cubePosDrawFrontCull = drawBuilder
                                    .PipelineState(pipelineBuilder)
                                    .Build();

            // Raycasting draw call.
            pipelineBuilder
            .PixelShader(_cubeDirShader)
            .RasterState(GorgonRasterState.Default);

            _cubeDirDrawCall = drawBuilder
                               .ConstantBuffer(ShaderType.Pixel, _volumeRayParams.GetView(), 0)
                               .PipelineState(pipelineBuilder)
                               .Build();
        }
コード例 #16
0
ファイル: Program.cs プロジェクト: ishkang/Gorgon
        /// <summary>
        /// Function to initialize the application.
        /// </summary>
        /// <returns>The main window.</returns>
        private static FormMain Initialize()
        {
            // Create our form and center on the primary monitor.
            FormMain window = GorgonExample.Initialize(new DX.Size2(1280, 800), "Gorgon MiniTri");

            try
            {
                // First we create and enumerate the list of video devices installed in the computer.
                // We must do this in order to tell Gorgon which video device we intend to use. Note that this method may be quite slow (particularly when running DEBUG versions of
                // Direct 3D). To counter this, this object and its Enumerate method are thread safe so this can be run in the background while keeping the main UI responsive.
                // Find out which devices we have installed in the system.

                // If no suitable device was found (no Direct 3D 12.0 support) in the computer, this method will throw an exception. However, if it succeeds, then the devices object
                // will be populated with the IGorgonVideoDeviceInfo for each video device in the system.
                //
                // Using this method, we could also enumerate the software rasterizer. These devices are typically used to determine if there's a driver error, and can be terribly slow to render
                // It is recommended that these only be used in diagnostic scenarios only.
                IReadOnlyList <IGorgonVideoAdapterInfo> deviceList = GorgonGraphics.EnumerateAdapters();

                if (deviceList.Count == 0)
                {
                    throw new
                          NotSupportedException("There are no suitable video adapters available in the system. This example is unable to continue and will now exit.");
                }

                // Now we create the main graphics interface with the first applicable video device.
                _graphics = new GorgonGraphics(deviceList[0]);

                // Check to ensure that we can support the format required for our swap chain.
                // If a video device can't support this format, then the odds are good it won't render anything. Since we're asking for a very common display format, this will
                // succeed nearly 100% of the time (unless you've somehow gotten an ancient video device to work with Direct 3D 11.1). Regardless, it's good form to the check for a
                // working display format prior to setting up the swap chain.
                //
                // This method is also used to determine if a format can be used for other objects (e.g. a texture, render target, etc...) Like the swap chain format, this is also a
                // best practice to check if the object you're creating supports the desired format.
                if ((_graphics.FormatSupport[BufferFormat.R8G8B8A8_UNorm].FormatSupport & BufferFormatSupport.Display) != BufferFormatSupport.Display)
                {
                    // We should never see this unless you've performed some form of black magic.
                    GorgonDialogs.ErrorBox(window, "We should not see this error.");
                    return(window);
                }

                // Finally, create a swap chain to display our output.
                // In this case we're setting up our swap chain to bind with our main window, and we use its client size to determine the width/height of the swap chain back buffers.
                // This width/height does not need to be the same size as the window, but, except for some scenarios, that would produce undesirable image quality.
                _swap = new GorgonSwapChain(_graphics,
                                            window,
                                            new GorgonSwapChainInfo("Main Swap Chain")
                {
                    Format = BufferFormat.R8G8B8A8_UNorm,
                    Width  = window.ClientSize.Width,
                    Height = window.ClientSize.Height
                })
                {
                    DoNotAutoResizeBackBuffer = true
                };

                // Create the shaders used to render the triangle.
                // These shaders provide transformation and coloring for the output pixel data.
                CreateShaders();

                // Set up our input layout.
                //
                // We'll be using this to describe to Direct 3D how the elements of a vertex is laid out in memory.
                // In order to provide synchronization between the layout on the CPU side and the GPU side, we have to pass the vertex shader because it will contain the vertex
                // layout to match with our C# input layout.
                _inputLayout = GorgonInputLayout.CreateUsingType <MiniTriVertex>(_graphics, _vertexShader);

                // Set up the triangle vertices.
                CreateVertexBuffer();

                // Set up the constant buffer.
                //
                // This is used (but could be used for more) to transform the vertex data from 3D space into 2D space.
                CreateConstantBuffer(window);

                // This defines where to send the pixel data when rendering. For now, this goes to our swap chain.
                _graphics.SetRenderTarget(_swap.RenderTargetView);

                // Create our draw call.
                //
                // This will pass all the necessary information to the GPU to render the triangle
                //
                // Since draw calls are immutable objects, we use builders to create them (and any pipeline state). Once a draw
                // call is built, it cannot be changed (except for the vertex, and if applicable, index, and instance ranges).
                //
                // Builders work on a fluent interface.  Much like LINQ and can be used to create multiple draw calls from the same
                // builder.
                var drawCallBuilder      = new GorgonDrawCallBuilder();
                var pipelineStateBuilder = new GorgonPipelineStateBuilder(_graphics);

                _drawCall = drawCallBuilder.VertexBuffer(_inputLayout, _vertexBuffer)
                            .VertexRange(0, 3)
                            .ConstantBuffer(ShaderType.Vertex, _constantBuffer)
                            .PipelineState(pipelineStateBuilder
                                           .PixelShader(_pixelShader)
                                           .VertexShader(_vertexShader)
                                           .RasterState(GorgonRasterState.NoCulling))
                            .Build();

                GorgonExample.LoadResources(_graphics);

                return(window);
            }
            finally
            {
                GorgonExample.EndInit();
            }
        }
コード例 #17
0
ファイル: Cube.cs プロジェクト: hammerforgegames/Gorgon
        /// <summary>
        /// Initializes a new instance of the <see cref="Cube"/> class.
        /// </summary>
        /// <param name="graphics">The graphics object used to create the buffers needed by this object.</param>
        /// <param name="inputLayout">The input layout describing how a vertex is laid out.</param>
        public Cube(GorgonGraphics graphics, GorgonInputLayout inputLayout)
        {
            GlassCubeVertex[] vertices =
            {
                // Front face.
                new GlassCubeVertex(new DX.Vector3(-0.5f,  0.5f, -0.5f), new DX.Vector2(0,       0)),
                new GlassCubeVertex(new DX.Vector3(0.5f,  -0.5f, -0.5f), new DX.Vector2(1.0f, 1.0f)),
                new GlassCubeVertex(new DX.Vector3(-0.5f, -0.5f, -0.5f), new DX.Vector2(0.0f, 1.0f)),
                new GlassCubeVertex(new DX.Vector3(0.5f,   0.5f, -0.5f), new DX.Vector2(1.0f, 0.0f)),

                // Right face.
                new GlassCubeVertex(new DX.Vector3(0.5f,   0.5f, -0.5f), new DX.Vector2(0,       0)),
                new GlassCubeVertex(new DX.Vector3(0.5f,  -0.5f,  0.5f), new DX.Vector2(1.0f, 1.0f)),
                new GlassCubeVertex(new DX.Vector3(0.5f,  -0.5f, -0.5f), new DX.Vector2(0.0f, 1.0f)),
                new GlassCubeVertex(new DX.Vector3(0.5f,   0.5f,  0.5f), new DX.Vector2(1.0f, 0.0f)),

                // Back face.
                new GlassCubeVertex(new DX.Vector3(0.5f,   0.5f,  0.5f), new DX.Vector2(0,       0)),
                new GlassCubeVertex(new DX.Vector3(-0.5f, -0.5f,  0.5f), new DX.Vector2(1.0f, 1.0f)),
                new GlassCubeVertex(new DX.Vector3(0.5f,  -0.5f,  0.5f), new DX.Vector2(0.0f, 1.0f)),
                new GlassCubeVertex(new DX.Vector3(-0.5f,  0.5f,  0.5f), new DX.Vector2(1.0f, 0.0f)),

                // Left face.
                new GlassCubeVertex(new DX.Vector3(-0.5f,  0.5f,  0.5f), new DX.Vector2(0,       0)),
                new GlassCubeVertex(new DX.Vector3(-0.5f, -0.5f, -0.5f), new DX.Vector2(1.0f, 1.0f)),
                new GlassCubeVertex(new DX.Vector3(-0.5f, -0.5f,  0.5f), new DX.Vector2(0.0f, 1.0f)),
                new GlassCubeVertex(new DX.Vector3(-0.5f,  0.5f, -0.5f), new DX.Vector2(1.0f, 0.0f)),

                // Top face.
                new GlassCubeVertex(new DX.Vector3(-0.5f,  0.5f,  0.5f), new DX.Vector2(0,       0)),
                new GlassCubeVertex(new DX.Vector3(0.5f,   0.5f, -0.5f), new DX.Vector2(1.0f, 1.0f)),
                new GlassCubeVertex(new DX.Vector3(-0.5f,  0.5f, -0.5f), new DX.Vector2(0.0f, 1.0f)),
                new GlassCubeVertex(new DX.Vector3(0.5f,   0.5f,  0.5f), new DX.Vector2(1.0f, 0.0f)),

                // Bottom face.
                new GlassCubeVertex(new DX.Vector3(-0.5f, -0.5f, -0.5f), new DX.Vector2(0,       0)),
                new GlassCubeVertex(new DX.Vector3(0.5f,  -0.5f,  0.5f), new DX.Vector2(1.0f, 1.0f)),
                new GlassCubeVertex(new DX.Vector3(-0.5f, -0.5f,  0.5f), new DX.Vector2(0.0f, 1.0f)),
                new GlassCubeVertex(new DX.Vector3(0.5f,  -0.5f, -0.5f), new DX.Vector2(1.0f, 0.0f))
            };

            ushort[] indices =
            {
                8,   9, 10,  8, 11,  9,
                12, 13, 14, 12, 15, 13,
                4,   5,  6,  4,  7,  5,
                16, 17, 18, 16, 19, 17,
                20, 21, 22, 20, 23, 21,
                0,   1,  2,  0,  3, 1
            };

            // Create our index buffer and vertex buffer and populate with our cube data.
            using (var indexPtr = GorgonNativeBuffer <ushort> .Pin(indices))
                using (var vertexPtr = GorgonNativeBuffer <GlassCubeVertex> .Pin(vertices))
                {
                    IndexBuffer = new GorgonIndexBuffer(graphics,
                                                        new GorgonIndexBufferInfo("GlassCube Index Buffer")
                    {
                        Usage           = ResourceUsage.Immutable,
                        IndexCount      = indices.Length,
                        Use16BitIndices = true
                    },
                                                        indexPtr);

                    VertexBuffer = new GorgonVertexBufferBindings(inputLayout)
                    {
                        [0] = GorgonVertexBufferBinding.CreateVertexBuffer(graphics,
                                                                           vertices.Length,
                                                                           ResourceUsage.Immutable,
                                                                           initialData: vertexPtr,
                                                                           bufferName: "GlassCube Vertex Buffer")
                    };
                }
        }