/// <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") }; } }
/// <summary> /// Initializes a new instance of the <see cref="Cube" /> class. /// </summary> /// <param name="graphics">The graphics interface.</param> /// <param name="size">The width, height and depth of the cube.</param> /// <param name="textureCoordinates">The texture coordinates for the faces of the cube.</param> /// <param name="angle">The initial orientation of the cube, in degrees.</param> /// <param name="columnsPerFace">The number of columns per face.</param> /// <param name="rowsPerFace">The number of rows per face.</param> public Cube(GorgonGraphics graphics, DX.Vector3 size, RectangleF textureCoordinates, DX.Vector3 angle, int columnsPerFace = 1, int rowsPerFace = 1) : base(graphics) { PrimitiveType = PrimitiveType.TriangleList; int faceVertexCount = (columnsPerFace + 1) * (rowsPerFace + 1); int faceIndexCount = (columnsPerFace * rowsPerFace) * 6; VertexCount = faceVertexCount * 6; IndexCount = faceIndexCount * 6; TriangleCount = IndexCount / 3; DX.Quaternion.RotationYawPitchRoll(angle.Y.ToRadians(), angle.X.ToRadians(), angle.Z.ToRadians(), out DX.Quaternion orientation); DX.Matrix.RotationQuaternion(ref orientation, out _orientation); using (var vertexData = new GorgonNativeBuffer <Vertex3D>(VertexCount)) using (var indexData = new GorgonNativeBuffer <int>(IndexCount)) { // Front. GetVertices(vertexData, 0, DX.Vector3.UnitY, -DX.Vector3.UnitZ, size, textureCoordinates, columnsPerFace, rowsPerFace); // Bottom. GetVertices(vertexData, faceVertexCount, -DX.Vector3.UnitZ, -DX.Vector3.UnitY, size, textureCoordinates, columnsPerFace, rowsPerFace); // Back. GetVertices(vertexData, faceVertexCount * 2, DX.Vector3.UnitY, DX.Vector3.UnitZ, size, textureCoordinates, columnsPerFace, rowsPerFace); // Top. GetVertices(vertexData, faceVertexCount * 3, DX.Vector3.UnitZ, DX.Vector3.UnitY, size, textureCoordinates, columnsPerFace, rowsPerFace); // Left. GetVertices(vertexData, faceVertexCount * 4, DX.Vector3.UnitY, -DX.Vector3.UnitX, size, textureCoordinates, columnsPerFace, rowsPerFace); // Right GetVertices(vertexData, faceVertexCount * 5, DX.Vector3.UnitY, DX.Vector3.UnitX, size, textureCoordinates, columnsPerFace, rowsPerFace); GetIndices(indexData, 0, 0, columnsPerFace, rowsPerFace); GetIndices(indexData, faceIndexCount, faceVertexCount, columnsPerFace, rowsPerFace); GetIndices(indexData, faceIndexCount * 2, faceVertexCount * 2, columnsPerFace, rowsPerFace); GetIndices(indexData, faceIndexCount * 3, faceVertexCount * 3, columnsPerFace, rowsPerFace); GetIndices(indexData, faceIndexCount * 4, faceVertexCount * 4, columnsPerFace, rowsPerFace); GetIndices(indexData, faceIndexCount * 5, faceVertexCount * 5, columnsPerFace, rowsPerFace); CalculateTangents(vertexData, indexData); VertexBuffer = new GorgonVertexBuffer(graphics, new GorgonVertexBufferInfo("CubeVB") { Usage = ResourceUsage.Immutable, SizeInBytes = vertexData.SizeInBytes }, vertexData.Cast <byte>()); IndexBuffer = new GorgonIndexBuffer(graphics, new GorgonIndexBufferInfo("CubeIB") { Usage = ResourceUsage.Immutable, Use16BitIndices = false, IndexCount = IndexCount }, indexData); } }
/// <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]; } } }
/// <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); } }
/// <summary> /// Initializes a new instance of the <see cref="Sphere" /> class. /// </summary> /// <param name="graphics">Graphics interface to use.</param> /// <param name="radius">Radius of the sphere</param> /// <param name="textureCoordinates">The texture coordinates to apply to the sphere.</param> /// <param name="angle">The angle of rotation, in degrees.</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, float radius, RectangleF textureCoordinates, DX.Vector3 angle, int ringCount = 8, int segmentCount = 16) : base(graphics) { // Calculate number of vertices and indices required for our sphere. PrimitiveType = PrimitiveType.TriangleList; VertexCount = (ringCount + 1) * (segmentCount + 1); IndexCount = 6 * ringCount * (segmentCount + 1); TriangleCount = IndexCount / 3; DX.Quaternion.RotationYawPitchRoll(angle.Y.ToRadians(), angle.X.ToRadians(), angle.Z.ToRadians(), out DX.Quaternion orientation); DX.Matrix.RotationQuaternion(ref orientation, out _orientation); using (var vertexData = new GorgonNativeBuffer <Vertex3D>(VertexCount)) using (var indexData = new GorgonNativeBuffer <int>(IndexCount)) { GetVertices(vertexData, indexData, radius, textureCoordinates, ringCount, segmentCount); VertexBuffer = new GorgonVertexBuffer(graphics, new GorgonVertexBufferInfo("SphereVertexBuffer") { Usage = ResourceUsage.Immutable, SizeInBytes = vertexData.SizeInBytes }, vertexData.Cast <byte>()); IndexBuffer = new GorgonIndexBuffer(graphics, new GorgonIndexBufferInfo("SphereIndexBuffer") { Usage = ResourceUsage.Immutable, Use16BitIndices = false, IndexCount = IndexCount }, indexData); } }
/// <summary> /// Initializes a new instance of the <see cref="Triangle" /> class. /// </summary> /// <param name="graphics">The graphics interface.</param> /// <param name="point1">The 1st point in the triangle.</param> /// <param name="point2">The 2nd point in the triangle.</param> /// <param name="point3">The 3rd point in the triangle.</param> public Triangle(GorgonGraphics graphics, Vertex3D point1, Vertex3D point2, Vertex3D point3) : base(graphics) { PrimitiveType = PrimitiveType.TriangleList; VertexCount = 3; IndexCount = 3; TriangleCount = 1; point1.Tangent = new DX.Vector4(1.0f, 0, 0, 1.0f); point2.Tangent = new DX.Vector4(1.0f, 0, 0, 1.0f); point3.Tangent = new DX.Vector4(1.0f, 0, 0, 1.0f); using (var points = new GorgonNativeBuffer <Vertex3D>(3)) using (var indices = new GorgonNativeBuffer <int>(3)) { points[0] = point1; points[1] = point2; points[2] = point3; indices[0] = 0; indices[1] = 1; indices[2] = 2; VertexBuffer = new GorgonVertexBuffer(graphics, new GorgonVertexBufferInfo("TriVB") { Usage = ResourceUsage.Immutable, SizeInBytes = Vertex3D.Size * 3 }, points.Cast <byte>()); IndexBuffer = new GorgonIndexBuffer(graphics, new GorgonIndexBufferInfo("TriIB") { Usage = ResourceUsage.Dynamic, Use16BitIndices = false, IndexCount = 3 }, indices); } }
/// <summary> /// Initializes a new instance of the <see cref="Plane" /> class. /// </summary> /// <param name="graphics">The graphics interface to use.</param> /// <param name="size">The width and height of the plane.</param> /// <param name="textureCoordinates">The texture coordinates to apply to the plane.</param> /// <param name="angle">The initial orientation, in degrees.</param> /// <param name="columns">The number of columns to subdivide by.</param> /// <param name="rows">The number of rows to subdivide by.</param> public Plane(GorgonGraphics graphics, DX.Vector2 size, RectangleF textureCoordinates, DX.Vector3 angle, int columns = 1, int rows = 1) : base(graphics) { PrimitiveType = PrimitiveType.TriangleStrip; VertexCount = (columns + 1) * (rows + 1); IndexCount = ((columns * rows) * 6) + (rows - 1); TriangleCount = (IndexCount - (rows - 1)) / 3; DX.Quaternion.RotationYawPitchRoll(angle.Y.ToRadians(), angle.X.ToRadians(), angle.Z.ToRadians(), out DX.Quaternion orientation); DX.Matrix.RotationQuaternion(ref orientation, out _orientation); using (var vertexData = new GorgonNativeBuffer <Vertex3D>(VertexCount)) using (var indexData = new GorgonNativeBuffer <int>(IndexCount)) { GetVertices(vertexData, size, textureCoordinates, columns, rows); GetIndices(indexData, columns, rows); CalculateTangents(vertexData, indexData); VertexBuffer = new GorgonVertexBuffer(graphics, new GorgonVertexBufferInfo("PlaneVB") { Usage = ResourceUsage.Immutable, SizeInBytes = vertexData.SizeInBytes }, vertexData.Cast <byte>()); IndexBuffer = new GorgonIndexBuffer(graphics, new GorgonIndexBufferInfo { Usage = ResourceUsage.Immutable, Use16BitIndices = false, IndexCount = IndexCount }, indexData); } }
/// <summary> /// Function to create the vertex/index buffers for the renderer. /// </summary> private void CreateBuffers() { // We don't need to update the index buffer ever. So we can set up the indices right now. using (var indices = new GorgonNativeBuffer <ushort>(MaxSpriteCount * 6)) { int indexOffset = 0; ushort index = 0; for (int i = 0; i < MaxSpriteCount; ++i) { indices[indexOffset++] = index; indices[indexOffset++] = (ushort)(index + 1); indices[indexOffset++] = (ushort)(index + 2); indices[indexOffset++] = (ushort)(index + 1); indices[indexOffset++] = (ushort)(index + 3); indices[indexOffset++] = (ushort)(index + 2); index += 4; } VertexBuffer = GorgonVertexBufferBinding.CreateVertexBuffer <Gorgon2DVertex>(Graphics, new GorgonVertexBufferInfo { Usage = ResourceUsage.Dynamic, Binding = VertexIndexBufferBinding.None, SizeInBytes = Gorgon2DVertex.SizeInBytes * (MaxSpriteCount * 4) }); IndexBuffer = new GorgonIndexBuffer(Graphics, new GorgonIndexBufferInfo { Usage = ResourceUsage.Immutable, Binding = VertexIndexBufferBinding.None, IndexCount = indices.Length }, indices); } }
/// <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)); }
/// <summary> /// Function to build the Icosphere. /// </summary> /// <param name="graphics">Graphics interface to use.</param> /// <param name="radius">Radius of the sphere.</param> /// <param name="tesselation">Tessellation factor for the sphere.</param> /// <param name="textureCoordinates">Texture coordinate offset and scale.</param> private void BuildSphere(GorgonGraphics graphics, float radius, int tesselation, DX.RectangleF textureCoordinates) { GetBaseVertices(); List <int[]> indices = GetBaseIndices(); for (int i = 0; i < tesselation; ++i) { var subIndices = new List <int[]>(); foreach (int[] index in indices) { int index0 = GetMiddlePoint(index[0], index[1]); int index1 = GetMiddlePoint(index[1], index[2]); int index2 = GetMiddlePoint(index[2], index[0]); subIndices.Add(new [] { index[0], index0, index2 }); subIndices.Add(new[] { index[1], index1, index0 }); subIndices.Add(new[] { index[2], index2, index1 }); subIndices.Add(new[] { index0, index1, index2 }); } indices = subIndices; _cachedSplits.Clear(); } // Perform texture coordinate calculations and vertex/normal transformations. const float piRecip = 1.0f / (float)System.Math.PI; const float pi2Recip = 1.0f / (2.0f * (float)System.Math.PI); // Final list. var vertexList = new List <Vertex3D>(); var indexList = new List <int>(); foreach (DX.Vector3 vector in _vertices) { DX.Vector3 position = vector; DX.Vector3 normal = position; DX.Vector2 uv = DX.Vector2.Zero; uv.X = ((0.5f - (position.X.ATan(position.Z) * pi2Recip)) * textureCoordinates.Width) + textureCoordinates.X; uv.Y = ((0.5f - (position.Y.ASin() * piRecip)) * textureCoordinates.Height) + textureCoordinates.Y; DX.Vector3.Multiply(ref position, radius, out position); DX.Vector3.TransformCoordinate(ref position, ref _orientation, out position); DX.Vector3.TransformCoordinate(ref normal, ref _orientation, out normal); normal.Normalize(); vertexList.Add(new Vertex3D { Position = new DX.Vector4(position, 1.0f), Normal = normal, UV = uv }); } foreach (int[] index in indices) { for (int j = 0; j < 3; ++j) { indexList.Add(index[j]); } } FixSeam(vertexList, indexList); using (var vertexData = GorgonNativeBuffer <Vertex3D> .Pin(vertexList.ToArray())) using (var indexData = GorgonNativeBuffer <int> .Pin(indexList.ToArray())) { VertexCount = vertexList.Count; IndexCount = indexList.Count; TriangleCount = IndexCount / 3; CalculateTangents(vertexData, indexData); VertexBuffer = new GorgonVertexBuffer(graphics, new GorgonVertexBufferInfo("IcoSphereVertexBuffer") { SizeInBytes = vertexData.SizeInBytes, Usage = ResourceUsage.Immutable }, vertexData.Cast <byte>()); IndexBuffer = new GorgonIndexBuffer(graphics, new GorgonIndexBufferInfo { Usage = ResourceUsage.Immutable, Use16BitIndices = false, IndexCount = IndexCount }, indexData); } }
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); }
/// <summary> /// Function to apply any state changes. /// </summary> /// <param name="renderable">Renderable object to retrieve states from.</param> /// <param name="state">States that need updating.</param> internal void UpdateState(IRenderable renderable, StateChange state) { GorgonRenderable.DepthStencilStates depthStencil = renderable.DepthStencil; GorgonRenderable.BlendState blending = renderable.Blending; GorgonRenderable.TextureSamplerState sampler = renderable.TextureSampler; if ((state & StateChange.Texture) == StateChange.Texture) { _resource = _graphics.Shaders.PixelShader.Resources[0] = renderable.Texture; // If we have a texture change, and we have the default diffuse shader loaded, then switch to the textured shader, otherwise // switch to the diffuse shader. Gorgon2D.PixelShader.TextureSwitch(renderable.Texture); } if ((state & StateChange.BlendFactor) == StateChange.BlendFactor) { _blendFactor = blending.BlendFactor; _graphics.Output.BlendingState.BlendFactor = blending.BlendFactor; } if ((state & StateChange.BlendState) == StateChange.BlendState) { _blendStates.RenderTarget0.IsBlendingEnabled = Gorgon2D.IsBlendingEnabled; _blendStates.RenderTarget0.AlphaOperation = blending.AlphaOperation; _blendStates.RenderTarget0.BlendingOperation = blending.BlendOperation; _blendStates.RenderTarget0.DestinationAlphaBlend = blending.DestinationAlphaBlend; _blendStates.RenderTarget0.DestinationBlend = blending.DestinationBlend; _blendStates.RenderTarget0.SourceAlphaBlend = blending.SourceAlphaBlend; _blendStates.RenderTarget0.SourceBlend = blending.SourceBlend; _blendStates.RenderTarget0.WriteMask = blending.WriteMask; _graphics.Output.BlendingState.States = _blendStates; } if ((state & StateChange.Sampler) == StateChange.Sampler) { _samplerState.HorizontalAddressing = sampler.HorizontalWrapping; _samplerState.VerticalAddressing = sampler.VerticalWrapping; _samplerState.BorderColor = sampler.BorderColor; _samplerState.TextureFilter = sampler.TextureFilter; _graphics.Shaders.PixelShader.TextureSamplers[0] = _samplerState; } if ((state & StateChange.Raster) == StateChange.Raster) { _rasterStates.IsScissorTestingEnabled = Gorgon2D.ClipRegion != null; _rasterStates.CullingMode = renderable.CullingMode; _rasterStates.IsMultisamplingEnabled = Gorgon2D.IsMultisamplingEnabled; _rasterStates.DepthBias = depthStencil.DepthBias; _graphics.Rasterizer.States = _rasterStates; } if ((state & StateChange.PrimitiveType) == StateChange.PrimitiveType) { _primitiveType = _graphics.Input.PrimitiveType = renderable.PrimitiveType; } if ((state & StateChange.IndexBuffer) == StateChange.IndexBuffer) { _indexBuffer = _graphics.Input.IndexBuffer = renderable.IndexBuffer; } if ((state & StateChange.VertexBuffer) == StateChange.VertexBuffer) { _vertexBuffer = _graphics.Input.VertexBuffers[0] = renderable.VertexBufferBinding; } if ((state & StateChange.AlphaTest) == StateChange.AlphaTest) { _alphaTest = new Gorgon2DAlphaTest(Gorgon2D.IsAlphaTestEnabled, renderable.AlphaTestValues); Gorgon2D.PixelShader.AlphaTestValuesBuffer.Update(ref _alphaTest); } if ((state & StateChange.DepthStencilReference) == StateChange.DepthStencilReference) { _depthStencilReference = _graphics.Output.DepthStencilState.StencilReference = depthStencil.StencilReference; } if ((state & StateChange.DepthStencil) != StateChange.DepthStencil) { return; } _depthStencilState.IsDepthEnabled = Gorgon2D.IsDepthBufferEnabled; _depthStencilState.IsDepthWriteEnabled = depthStencil.IsDepthWriteEnabled; _depthStencilState.DepthComparison = depthStencil.DepthComparison; _depthStencilState.StencilReadMask = depthStencil.StencilReadMask; _depthStencilState.StencilWriteMask = depthStencil.StencilWriteMask; _depthStencilState.IsStencilEnabled = Gorgon2D.IsStencilEnabled; _depthStencilState.StencilFrontFace.ComparisonOperator = depthStencil.FrontFace.ComparisonOperator; _depthStencilState.StencilFrontFace.DepthFailOperation = depthStencil.FrontFace.DepthFailOperation; _depthStencilState.StencilFrontFace.FailOperation = depthStencil.FrontFace.FailOperation; _depthStencilState.StencilFrontFace.PassOperation = depthStencil.FrontFace.PassOperation; _depthStencilState.StencilBackFace.ComparisonOperator = depthStencil.BackFace.ComparisonOperator; _depthStencilState.StencilBackFace.DepthFailOperation = depthStencil.BackFace.DepthFailOperation; _depthStencilState.StencilBackFace.FailOperation = depthStencil.BackFace.FailOperation; _depthStencilState.StencilBackFace.PassOperation = depthStencil.BackFace.PassOperation; _graphics.Output.DepthStencilState.States = _depthStencilState; }
/// <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); } }
/// <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") }; } }