/// <summary> /// Function to initialize the states for the objects to draw. /// </summary> private static void InitializeStates() { var drawBuilder = new GorgonDrawIndexCallBuilder(); var stateBuilder = new GorgonPipelineStateBuilder(_graphics); GorgonSamplerState sampler = new GorgonSamplerStateBuilder(_graphics) .Filter(SampleFilter.MinMagMipPoint) .Wrapping(TextureWrap.Wrap, TextureWrap.Wrap) .Build(); // Initialize our draw call so we can render the objects. // All objects are using triangle lists, so we must tell the draw call that's what we need to render. for (int i = 0; i < 2; ++i) { _planes[i].Material.TextureSampler = sampler; _drawCalls[i] = drawBuilder.VertexBuffer(_inputLayout, _planes[i].VertexBufferBindings[0]) .IndexBuffer(_planes[i].IndexBuffer, 0, _planes[i].IndexBuffer.IndexCount) .SamplerState(ShaderType.Pixel, sampler) .ShaderResource(ShaderType.Pixel, _planes[i].Material.Texture) .ConstantBuffer(ShaderType.Vertex, _wvpBuffer) .ConstantBuffer(ShaderType.Pixel, _materialBuffer) .PipelineState(stateBuilder.DepthStencilState(GorgonDepthStencilState.DepthStencilEnabledGreaterEqual) .PixelShader(_pixelShader) .VertexShader(_vertexShader)) .Build(); } // For our sphere, we can just reuse the builder(s) since only a small part of the resources have changed. _sphere.Material.TextureSampler = sampler; _drawCalls[2] = drawBuilder.VertexBuffer(_inputLayout, _sphere.VertexBufferBindings[0]) .ShaderResource(ShaderType.Pixel, _sphere.Material.Texture) .IndexBuffer(_sphere.IndexBuffer, 0, _sphere.IndexBuffer.IndexCount) .Build(); // 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. DX.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 = DX.Matrix.PerspectiveFovLH((75.0f).ToRadians(), _mainForm.ClientSize.Width / (float)_mainForm.ClientSize.Height, 500.0f, 0.125f); }
/// <summary>Function called to perform custom loading of resources.</summary> protected override void OnLoad() { base.OnLoad(); if (_builder == null) { _builder = new GorgonSamplerStateBuilder(Graphics); } _current = SpriteContent.SamplerState; SpriteContent.WrappingEditor.HorizontalWrapping = _current.WrapU; SpriteContent.WrappingEditor.VerticalWrapping = _current.WrapV; SpriteContent.WrappingEditor.OriginalBorderColor = SpriteContent.WrappingEditor.BorderColor = _current.BorderColor; SpriteContent.WrappingEditor.PropertyChanged += WrappingEditor_PropertyChanged; BuildSpriteRtv(); }
/// <summary> /// Function to build a sampler state from the information provided by the sprite data. /// </summary> /// <param name="graphics">The graphics interface to use.</param> /// <param name="filter">The filter to use.</param> /// <param name="borderColor">The color of the border to use.</param> /// <param name="hWrap">Horizontal wrapping mode.</param> /// <param name="vWrap">Vertical wrapping mode.</param> /// <returns>The sampler state.</returns> private static GorgonSamplerState CreateSamplerState(GorgonGraphics graphics, SampleFilter filter, GorgonColor borderColor, TextureWrap hWrap, TextureWrap vWrap) { var builder = new GorgonSamplerStateBuilder(graphics); switch (filter) { case SampleFilter.MinMagMipLinear when(hWrap == TextureWrap.Clamp) && (vWrap == TextureWrap.Clamp) && (borderColor == GorgonColor.White): return(null); case SampleFilter.MinMagMipPoint when(hWrap == TextureWrap.Clamp) && (vWrap == TextureWrap.Clamp) && (borderColor == GorgonColor.White): return(GorgonSamplerState.PointFiltering); case SampleFilter.MinMagMipLinear when(hWrap == TextureWrap.Wrap) && (vWrap == TextureWrap.Wrap) && (borderColor == GorgonColor.White): return(GorgonSamplerState.Wrapping); case SampleFilter.MinMagMipPoint when(hWrap == TextureWrap.Wrap) && (vWrap == TextureWrap.Wrap) && (borderColor == GorgonColor.White): return(GorgonSamplerState.PointFilteringWrapping); default: return(builder.Wrapping(hWrap, vWrap, borderColor: borderColor) .Filter(filter) .Build()); } }
/// <summary> /// Function to assign a sampler to a shader on the pipeline. /// </summary> /// <param name="sampler">The sampler to assign.</param> /// <param name="index">[Optional] The index of the sampler.</param> /// <returns>The fluent interface for this builder.</returns> /// <exception cref="ArgumentOutOfRangeException">Thrown if the <paramref name="index"/> parameter is less than 0, or greater than/equal to <see cref="GorgonSamplerStates.MaximumSamplerStateCount"/>.</exception> public Gorgon2DShaderStateBuilder <T> SamplerState(GorgonSamplerStateBuilder sampler, int index = 0) => SamplerState(sampler.Build(), index);
/// <summary> /// Function to read the sprite data from a stream. /// </summary> /// <param name="stream">The stream containing the sprite.</param> /// <param name="byteCount">The number of bytes to read from the stream.</param> /// <param name="overrideTexture">The texture to assign to the sprite instead of the texture associated with the name stored in the file.</param> /// <returns>A new <see cref="GorgonPolySprite"/>.</returns> protected override GorgonPolySprite OnReadFromStream(Stream stream, int byteCount, GorgonTexture2DView overrideTexture) { var reader = new GorgonChunkFileReader(stream, new[] { CurrentFileHeader }); GorgonBinaryReader binReader = null; var sprite = new GorgonPolySpriteBuilder(Renderer); try { reader.Open(); binReader = reader.OpenChunk(SpriteData); sprite.Anchor(binReader.ReadValue <DX.Vector2>()); // If we do not have alpha test information, then skip writing its data. if (binReader.ReadBoolean()) { sprite.AlphaTest(binReader.ReadValue <GorgonRangeF>()); } reader.CloseChunk(); binReader = reader.OpenChunk(VertexData); int vertexCount = binReader.ReadInt32(); for (int i = 0; i < vertexCount; ++i) { sprite.AddVertex(new GorgonPolySpriteVertex(binReader.ReadValue <DX.Vector2>(), binReader.ReadValue <GorgonColor>(), binReader.ReadValue <DX.Vector2>())); } reader.CloseChunk(); if (reader.Chunks.Contains(TextureData)) { binReader = reader.OpenChunk(TextureData); sprite.Texture(LoadTexture(binReader, overrideTexture, out DX.Vector2 textureOffset, out DX.Vector2 textureScale, out int textureArrayIndex)); sprite.TextureArrayIndex(textureArrayIndex); sprite.TextureTransform(textureOffset, textureScale); reader.CloseChunk(); } if (!reader.Chunks.Contains(TextureSamplerData)) { return(sprite.Build()); } var builder = new GorgonSamplerStateBuilder(Renderer.Graphics); binReader = reader.OpenChunk(TextureSamplerData); binReader.ReadValue(out SampleFilter filter); binReader.ReadValue(out GorgonColor borderColor); binReader.ReadValue(out Comparison compareFunc); binReader.ReadValue(out TextureWrap wrapU); binReader.ReadValue(out TextureWrap wrapV); binReader.ReadValue(out TextureWrap wrapW); binReader.ReadValue(out int maxAnisotropy); binReader.ReadValue(out float minLod); binReader.ReadValue(out float maxLod); binReader.ReadValue(out float mipLodBias); reader.CloseChunk(); sprite.TextureSampler(builder.Wrapping(wrapU, wrapV, wrapW, borderColor) .Filter(filter) .ComparisonFunction(compareFunc) .MaxAnisotropy(maxAnisotropy) .MipLevelOfDetail(minLod, maxLod, mipLodBias) .Build()); return(sprite.Build()); } finally { binReader?.Dispose(); reader.Close(); } }
/// <summary> /// Function to read the sprite data from a stream. /// </summary> /// <param name="stream">The stream containing the sprite.</param> /// <param name="byteCount">The number of bytes to read from the stream.</param> /// <param name="overrideTexture">The texture to assign to the sprite instead of the texture associated with the name stored in the file.</param> /// <returns>A new <see cref="GorgonSprite"/>.</returns> protected override GorgonSprite OnReadFromStream(Stream stream, int byteCount, GorgonTexture2DView overrideTexture) { var reader = new GorgonChunkFileReader(stream, new[] { CurrentFileHeader }); GorgonBinaryReader binReader = null; var sprite = new GorgonSprite(); try { reader.Open(); binReader = reader.OpenChunk(SpriteData); sprite.Size = binReader.ReadValue <DX.Size2F>(); sprite.Anchor = binReader.ReadValue <DX.Vector2>(); // If we do not have alpha test information, then skip writing its data. if (binReader.ReadBoolean()) { sprite.AlphaTest = binReader.ReadValue <GorgonRangeF>(); } // Write out corner data. sprite.CornerOffsets.UpperLeft = binReader.ReadValue <DX.Vector3>(); sprite.CornerOffsets.UpperRight = binReader.ReadValue <DX.Vector3>(); sprite.CornerOffsets.LowerLeft = binReader.ReadValue <DX.Vector3>(); sprite.CornerOffsets.LowerRight = binReader.ReadValue <DX.Vector3>(); sprite.CornerColors.UpperLeft = binReader.ReadValue <GorgonColor>(); sprite.CornerColors.UpperRight = binReader.ReadValue <GorgonColor>(); sprite.CornerColors.LowerLeft = binReader.ReadValue <GorgonColor>(); sprite.CornerColors.LowerRight = binReader.ReadValue <GorgonColor>(); reader.CloseChunk(); if (reader.Chunks.Contains(TextureData)) { binReader = reader.OpenChunk(TextureData); sprite.Texture = LoadTexture(binReader, overrideTexture, out DX.RectangleF textureCoordinates, out int textureArrayIndex); sprite.TextureRegion = textureCoordinates; sprite.TextureArrayIndex = textureArrayIndex; reader.CloseChunk(); } if (!reader.Chunks.Contains(TextureSamplerData)) { return(sprite); } var builder = new GorgonSamplerStateBuilder(Renderer.Graphics); binReader = reader.OpenChunk(TextureSamplerData); binReader.ReadValue(out SampleFilter filter); binReader.ReadValue(out GorgonColor borderColor); binReader.ReadValue(out Comparison compareFunc); binReader.ReadValue(out TextureWrap wrapU); binReader.ReadValue(out TextureWrap wrapV); binReader.ReadValue(out TextureWrap wrapW); binReader.ReadValue(out int maxAnisotropy); binReader.ReadValue(out float minLod); binReader.ReadValue(out float maxLod); binReader.ReadValue(out float mipLodBias); reader.CloseChunk(); sprite.TextureSampler = builder.Wrapping(wrapU, wrapV, wrapW, borderColor) .Filter(filter) .ComparisonFunction(compareFunc) .MaxAnisotropy(maxAnisotropy) .MipLevelOfDetail(minLod, maxLod, mipLodBias) .Build(); return(sprite); } finally { binReader?.Dispose(); reader.Close(); } }
/// <summary>Initializes a new instance of the <see cref="SamplerBuildService"/> class.</summary> /// <param name="builder">The builder used to create the sampler state.</param> public SamplerBuildService(GorgonSamplerStateBuilder builder) => _builder = builder;
/// <summary>Reads the JSON representation of the object.</summary> /// <param name="reader">The <see cref="T:Newtonsoft.Json.JsonReader" /> to read from.</param> /// <param name="objectType">Type of the object.</param> /// <param name="existingValue">The existing value of object being read. If there is no existing value then <c>null</c> will be used.</param> /// <param name="hasExistingValue">The existing value has a value.</param> /// <param name="serializer">The calling serializer.</param> /// <returns>The object value.</returns> public override GorgonSamplerState ReadJson(JsonReader reader, Type objectType, GorgonSamplerState existingValue, bool hasExistingValue, JsonSerializer serializer) { if ((reader.TokenType != JsonToken.StartObject) || (_graphics == null)) { return(null); } GorgonColor? borderColor = null; Comparison? compareFunction = null; SampleFilter?filter = null; int? maxAnisotropy = null; float? maxLod = null; float? minLod = null; float? mipLodBias = null; TextureWrap? wrapU = null; TextureWrap? wrapV = null; TextureWrap? wrapW = null; var builder = new GorgonSamplerStateBuilder(_graphics); while ((reader.Read()) && (reader.TokenType != JsonToken.EndObject)) { if (reader.TokenType != JsonToken.PropertyName) { continue; } switch (reader.Value.ToString()) { case "borderColor": borderColor = reader.ReadAsInt32(); break; case "compareFunc": compareFunction = (Comparison?)reader.ReadAsInt32(); break; case "filter": filter = (SampleFilter?)reader.ReadAsInt32(); break; case "maxAnisotropy": maxAnisotropy = reader.ReadAsInt32(); break; case "maxLod": maxLod = (float?)reader.ReadAsDouble(); break; case "minLod": minLod = (float?)reader.ReadAsDouble(); break; case "mipLodBias": mipLodBias = (float?)reader.ReadAsDouble(); break; case "wrapU": wrapU = (TextureWrap?)reader.ReadAsInt32(); break; case "wrapV": wrapV = (TextureWrap?)reader.ReadAsInt32(); break; case "wrapW": wrapW = (TextureWrap?)reader.ReadAsInt32(); break; } } return(builder.Wrapping(wrapU, wrapV, wrapW, borderColor) .MaxAnisotropy(maxAnisotropy ?? 1) .ComparisonFunction(compareFunction ?? Comparison.Never) .Filter(filter ?? SampleFilter.MinMagMipLinear) .MipLevelOfDetail(minLod ?? float.MinValue, maxLod ?? float.MaxValue, mipLodBias ?? 0) .Build()); }