Beispiel #1
0
        public Dx11PipelineState(Dx11RenderingDevice device, string shaderName, InputElement[] inputElements)
        {
            // Vertex shader
            using (Stream VertexShaderStream = ThisAssembly.GetManifestResourceStream("DxShaders." + shaderName + "VS"))
            {
                if (VertexShaderStream == null)
                {
                    throw new Exception("Vertex shader for \"" + shaderName + "\" not found.");
                }
                byte[] VertexShaderBytes = new byte[VertexShaderStream.Length];
                VertexShaderStream.Read(VertexShaderBytes, 0, VertexShaderBytes.Length);
                VertexShader = new VertexShader(device.Device, VertexShaderBytes);
                VertexShader.SetDebugName(shaderName);

                // Input layout
                InputLayout = new InputLayout(device.Device, VertexShaderBytes, inputElements);
                InputLayout.SetDebugName(shaderName);
            }

            // Pixel shader
            using (Stream PixelShaderStream = ThisAssembly.GetManifestResourceStream("DxShaders." + shaderName + "PS"))
            {
                if (PixelShaderStream == null)
                {
                    throw new Exception("Pixel shader for \"" + shaderName + "\" not found.");
                }
                byte[] PixelShaderBytes = new byte[PixelShaderStream.Length];
                PixelShaderStream.Read(PixelShaderBytes, 0, PixelShaderBytes.Length);
                PixelShader = new PixelShader(device.Device, PixelShaderBytes);
                PixelShader.SetDebugName(shaderName);
            }
        }
Beispiel #2
0
        public unsafe Dx11RenderingDrawingTest(Dx11RenderingDevice device, Description description)
        {
            Device = device;

            // Create buffer
            const int vertexCount = 3;
            int       size        = vertexCount * (sizeof(Vector3) + sizeof(uint));

            fixed(byte *data = new byte[size])
            {
                Vector3 *positions = (Vector3 *)(data);
                uint *   colors    = (uint *)(data + vertexCount * sizeof(Vector3));

                // Setup vertices
                positions[0] = new Vector3(0.0f, 0.0f, 0.0f);
                colors[0]    = 0xff000080;
                positions[1] = new Vector3(0.0f, 1.0f, 0.0f);
                colors[1]    = 0xff008000;
                positions[2] = new Vector3(1.0f, 0.0f, 0.0f);
                colors[2]    = 0xff800000;

                // Create GPU resources
                VertexBuffer = new Buffer(device.Device, new IntPtr(data),
                                          new BufferDescription(size, ResourceUsage.Immutable, BindFlags.VertexBuffer,
                                                                CpuAccessFlags.None, ResourceOptionFlags.None, 0));
                VertexBufferBindings = new VertexBufferBinding[] {
                    new VertexBufferBinding(VertexBuffer, sizeof(Vector3), (int)((byte *)positions - data)),
                    new VertexBufferBinding(VertexBuffer, sizeof(uint), (int)((byte *)colors - data))
                };
            }
        }
Beispiel #3
0
        public override unsafe void RenderSprites(RenderingTextureAllocator textureAllocator, bool linearFilter, params Sprite[] sprites)
        {
            Vector2 textureScaling = new Vector2(16777216.0f) / new Vector2(textureAllocator.Size.X, textureAllocator.Size.Y);

            // Build vertex buffer
            int vertexCount = sprites.Length * 6;
            int bufferSize  = vertexCount * (sizeof(Vector2) + sizeof(ulong));

            fixed(byte *data = new byte[bufferSize])
            {
                Vector2 *positions = (Vector2 *)(data);
                ulong *  uvws      = (ulong *)(data + vertexCount * sizeof(Vector2));

                // Setup vertices
                int count = sprites.Length;

                for (int i = 0; i < count; ++i)
                {
                    Sprite     sprite  = sprites[i];
                    VectorInt3 texPos  = textureAllocator.Get(sprite.Texture);
                    VectorInt2 texSize = sprite.Texture.To - sprite.Texture.From;

                    positions[i * 6 + 0] = sprite.Pos00;
                    positions[i * 6 + 2] = positions[i * 6 + 3] = sprite.Pos10;
                    positions[i * 6 + 1] = positions[i * 6 + 4] = sprite.Pos01;
                    positions[i * 6 + 5] = sprite.Pos11;
                    uvws[i * 6 + 1]      = uvws[i * 6 + 4] = Dx11RenderingDevice.CompressUvw(texPos, textureScaling, new Vector2(0.5f, 0.5f));
                    uvws[i * 6 + 5]      = Dx11RenderingDevice.CompressUvw(texPos, textureScaling, new Vector2(texSize.X - 0.5f, 0.5f));
                    uvws[i * 6 + 0]      = Dx11RenderingDevice.CompressUvw(texPos, textureScaling, new Vector2(0.5f, texSize.Y - 0.5f));
                    uvws[i * 6 + 2]      = uvws[i * 6 + 3] = Dx11RenderingDevice.CompressUvw(texPos, textureScaling, new Vector2(texSize.X - 0.5f, texSize.Y - 0.5f));
                }

                // Create GPU resources
                using (var VertexBuffer = new Buffer(Device.Device, new IntPtr(data),
                                                     new BufferDescription(bufferSize, ResourceUsage.Immutable, BindFlags.VertexBuffer,
                                                                           CpuAccessFlags.None, ResourceOptionFlags.None, 0)))
                {
                    var VertexBufferBindings = new VertexBufferBinding[] {
                        new VertexBufferBinding(VertexBuffer, sizeof(Vector2), (int)((byte *)positions - data)),
                        new VertexBufferBinding(VertexBuffer, sizeof(ulong), (int)((byte *)uvws - data))
                    };

                    // Render
                    Bind();
                    Device.SpriteShader.Apply(Device.Context);
                    Device.Context.PixelShader.SetSampler(0, linearFilter ? Device.SamplerDefault : Device.SamplerRoundToNearest);
                    Device.Context.PixelShader.SetShaderResources(0, ((Dx11RenderingTextureAllocator)(textureAllocator)).TextureView);
                    Device.Context.InputAssembler.SetVertexBuffers(0, VertexBufferBindings);
                    Device.Context.OutputMerger.SetDepthStencilState(Device.DepthStencilNoZBuffer);

                    // Render
                    Device.Context.Draw(vertexCount, 0);

                    // Reset state
                    Device.Context.OutputMerger.SetDepthStencilState(Device.DepthStencilDefault);
                }
            }
        }
Beispiel #4
0
 public Dx11RenderingSwapChain(Dx11RenderingDevice device, Description description)
 {
     Device    = device;
     Size      = description.Size;
     SwapChain = new SwapChain(device.Factory, device.Device,
                               new SwapChainDescription
     {
         BufferCount       = BufferCount,
         ModeDescription   = new ModeDescription(Size.X, Size.Y, RefreshRate, Format),
         IsWindowed        = true,
         OutputHandle      = description.WindowHandle,
         SampleDescription = new SampleDescription(GetAntialiasQuality(description.Antialias ? 4 : 1), 0),
         SwapEffect        = SwapEffect.Sequential,
         Usage             = Usage.RenderTargetOutput
     });
     device.Factory.MakeWindowAssociation(description.WindowHandle, WindowAssociationFlags.IgnoreAll);
     CreateBuffersAndViews();
 }
Beispiel #5
0
        public Dx11RenderingTextureAllocator(Dx11RenderingDevice device, Description description)
            : base(device, description)
        {
            Context = device.Context;

            Texture2DDescription dx11Description;

            dx11Description.ArraySize         = description.Size.Z;
            dx11Description.BindFlags         = BindFlags.ShaderResource;
            dx11Description.CpuAccessFlags    = CpuAccessFlags.None;
            dx11Description.Format            = SharpDX.DXGI.Format.B8G8R8A8_UNorm;
            dx11Description.Height            = description.Size.X;
            dx11Description.MipLevels         = MipLevelCount;
            dx11Description.OptionFlags       = ResourceOptionFlags.None;
            dx11Description.SampleDescription = new SharpDX.DXGI.SampleDescription(1, 0);
            dx11Description.Usage             = ResourceUsage.Default; // Perhaps dynamic could be used?
            dx11Description.Width             = description.Size.Y;
            Texture     = new Texture2D(device.Device, dx11Description);
            TextureView = new ShaderResourceView(device.Device, Texture);
        }
Beispiel #6
0
        public unsafe RenderingTextureAllocator.GarbageCollectionAdjustDelegate GarbageCollectTexture(RenderingTextureAllocator allocator,
                                                                                                      RenderingTextureAllocator.Map map, HashSet <RenderingTextureAllocator.Map.Entry> inOutUsedTextures)
        {
            TexturesInvalidated = true;
            if (VertexBuffer == null)
            {
                return(null);
            }

            byte[]  data                   = Device.ReadBuffer(VertexBuffer, VertexBufferSize);
            Vector2 textureScaling         = new Vector2(16777216.0f) / new Vector2(TextureAllocator.Size.X, TextureAllocator.Size.Y);
            int     uvwAndBlendModesOffset = VertexBufferBindings[3].Offset;

            // Collect all used textures
            fixed(byte *dataPtr = data)
            {
                ulong *uvwAndBlendModesPtr = (ulong *)(dataPtr + uvwAndBlendModesOffset);

                for (int i = 0; i < VertexCount; ++i)
                {
                    if (uvwAndBlendModesPtr[i] < 0x1000000) // Very small coordinates make no sense, they are used as a placeholder
                    {
                        continue;
                    }
                    var texture = map.Lookup(Dx11RenderingDevice.UncompressUvw(uvwAndBlendModesPtr[i], textureScaling));
                    if (texture == null)
#if DEBUG
                    { throw new ArgumentOutOfRangeException("Texture unrecognized."); }
#else
                    { continue; }
#endif
                    inOutUsedTextures.Add(texture);
                }
            }

            // Provide a methode to update the buffer with new UV coordinates
            return(delegate(RenderingTextureAllocator allocator2, RenderingTextureAllocator.Map map2)
            {
                Vector2 textureScaling2 = new Vector2(16777216.0f) / new Vector2(TextureAllocator.Size.X, TextureAllocator.Size.Y);

                // Update data
                fixed(byte *dataPtr = data)
                {
                    ulong *uvwAndBlendModesPtr = (ulong *)(dataPtr + uvwAndBlendModesOffset);
                    for (int i = 0; i < VertexCount; ++i)
                    {
                        if (uvwAndBlendModesPtr[i] < 0x1000000) // Very small coordinates make no sense, they are used as a placeholder
                        {
                            continue;
                        }
                        var texture = map.Lookup(Dx11RenderingDevice.UncompressUvw(uvwAndBlendModesPtr[i], textureScaling));
                        Vector2 uv;
                        uint highestBits;
                        Dx11RenderingDevice.UncompressUvw(uvwAndBlendModesPtr[i], texture.Pos, textureScaling, out uv, out highestBits);
                        uvwAndBlendModesPtr[i] = Dx11RenderingDevice.CompressUvw(allocator2.Get(texture.Texture), textureScaling2, uv, highestBits);
                    }
                }

                // Upload data
                var oldVertexBuffer = VertexBuffer;
                fixed(byte *dataPtr = data)
                {
                    VertexBuffer = new Buffer(Device.Device, new IntPtr(dataPtr),
                                              new BufferDescription(VertexBufferSize, ResourceUsage.Immutable, BindFlags.VertexBuffer,
                                                                    CpuAccessFlags.None, ResourceOptionFlags.None, 0));
                    oldVertexBuffer.Dispose();
                }

                for (int i = 0; i < VertexBufferBindings.Length; ++i)
                {
                    if (VertexBufferBindings[i].Buffer == oldVertexBuffer)
                    {
                        VertexBufferBindings[i].Buffer = VertexBuffer;
                    }
                }
            });
        }
Beispiel #7
0
        public unsafe Dx11RenderingDrawingRoom(Dx11RenderingDevice device, Description description)
        {
            Device           = device;
            TextureView      = ((Dx11RenderingTextureAllocator)(description.TextureAllocator)).TextureView;
            TextureAllocator = description.TextureAllocator;
            Vector2 textureScaling = new Vector2(16777216.0f) / new Vector2(TextureAllocator.Size.X, TextureAllocator.Size.Y);

            RoomGeometry roomGeometry = description.Room.RoomGeometry;

            // Create buffer
            Vector3 worldPos = description.Room.WorldPos + description.Offset;
            int     singleSidedVertexCount = roomGeometry.VertexPositions.Count;
            int     vertexCount            = VertexCount = singleSidedVertexCount + roomGeometry.DoubleSidedTriangleCount * 3;

            if (vertexCount == 0)
            {
                return;
            }
            VertexBufferSize = vertexCount * (sizeof(Vector3) + sizeof(uint) + sizeof(uint) + sizeof(ulong) + sizeof(uint));
            fixed(byte *data = new byte[VertexBufferSize])
            {
                Vector3 *positions                = (Vector3 *)(data);
                uint *   colors                   = (uint *)(data + vertexCount * sizeof(Vector3));
                uint *   overlays                 = (uint *)(data + vertexCount * (sizeof(Vector3) + sizeof(uint)));
                ulong *  uvwAndBlendModes         = (ulong *)(data + vertexCount * (sizeof(Vector3) + sizeof(uint) + sizeof(uint)));
                uint *   editorUVAndSectorTexture = (uint *)(data + vertexCount * (sizeof(Vector3) + sizeof(uint) + sizeof(uint) + sizeof(ulong)));

                // Setup vertices
                for (int i = 0; i < singleSidedVertexCount; ++i)
                {
                    positions[i] = roomGeometry.VertexPositions[i] + worldPos;
                }
                for (int i = 0; i < singleSidedVertexCount; ++i)
                {
                    colors[i] = Dx11RenderingDevice.CompressColor(roomGeometry.VertexColors[i]);
                }
                for (int i = 0; i < singleSidedVertexCount; ++i)
                {
                    Vector2 vertexEditorUv = roomGeometry.VertexEditorUVs[i];
                    uint    editorUv       = 0;
                    editorUv |= (uint)((int)vertexEditorUv.X) & 3;
                    editorUv |= ((uint)((int)vertexEditorUv.Y) & 3) << 2;
                    editorUVAndSectorTexture[i] = editorUv;
                }
                {
                    SectorInfo lastSectorInfo    = new SectorInfo(-1, -1, BlockFace.Floor);
                    uint       lastSectorTexture = 0;
                    uint       overlay           = 0;
                    for (int i = 0, triangleCount = singleSidedVertexCount / 3; i < triangleCount; ++i)
                    {
                        SectorInfo currentSectorInfo = roomGeometry.TriangleSectorInfo[i];
                        if (!lastSectorInfo.Equals(currentSectorInfo))
                        {
                            SectorTextureResult result = description.SectorTextureGet(description.Room, currentSectorInfo.Pos.X, currentSectorInfo.Pos.Y, currentSectorInfo.Face);

                            lastSectorInfo    = currentSectorInfo;
                            lastSectorTexture = 0;
                            if (result.SectorTexture != SectorTexture.None)
                            { // Use sector texture
                                lastSectorTexture = 0x40 | (((uint)result.SectorTexture - 1) << 8);
                            }
                            else
                            { // Use sector color
                                lastSectorTexture =
                                    (((uint)(result.Color.X * 255)) << 8) |
                                    (((uint)(result.Color.Y * 255)) << 16) |
                                    (((uint)(result.Color.Z * 255)) << 24);
                            }
                            // Highlight / dim sectors
                            if (result.Highlighted)
                            {
                                lastSectorTexture |= 0x10;
                            }
                            if (result.Dimmed)
                            {
                                lastSectorTexture |= 0x20;
                            }
                            // Indicate selected textured faces
                            if (result.Selected && roomGeometry.TriangleTextureAreas[i].Texture != null)
                            {
                                lastSectorTexture |= 0x80;
                            }

                            // Assign overlay color which will be used in geometry mode if face has service texture (e.g. arrows)
                            overlay = Dx11RenderingDevice.CompressColor(new Vector3(result.Overlay.X, result.Overlay.Y, result.Overlay.Z), (result.Hidden ? 0.4f : 1.0f), false);
                        }
                        editorUVAndSectorTexture[i * 3 + 0] |= lastSectorTexture;
                        editorUVAndSectorTexture[i * 3 + 1] |= lastSectorTexture;
                        editorUVAndSectorTexture[i * 3 + 2] |= lastSectorTexture;

                        overlays[i * 3 + 0] = overlay;
                        overlays[i * 3 + 1] = overlay;
                        overlays[i * 3 + 2] = overlay;
                    }
                }

RetryTexturing:
                ;
                {
                    int doubleSidedVertexIndex = singleSidedVertexCount;
                    for (int i = 0, triangleCount = singleSidedVertexCount / 3; i < triangleCount; ++i)
                    {
                        TextureArea texture = roomGeometry.TriangleTextureAreas[i];

                        if (texture.Texture == null)
                        { // Render as geometry
                            uvwAndBlendModes[i * 3 + 0] = 1ul << 24;
                            uvwAndBlendModes[i * 3 + 1] = 1ul << 24;
                            uvwAndBlendModes[i * 3 + 2] = 1ul << 24;
                        }
                        else if (texture.Texture is TextureInvisible)
                        { // Render as invisible
                            uvwAndBlendModes[i * 3 + 0] = 0ul << 24;
                            uvwAndBlendModes[i * 3 + 1] = 0ul << 24;
                            uvwAndBlendModes[i * 3 + 2] = 0ul << 24;
                        }
                        else
                        {
                            // Render as textured (the texture may turn out to be unavailable)
                            if (texture.Texture.IsUnavailable)
                            { // Texture is unvailable (i.e. file couldn't be loaded.
                                ImageC     image    = Dx11RenderingDevice.TextureUnavailable;
                                VectorInt3 position = TextureAllocator.Get(image);
                                uvwAndBlendModes[i * 3 + 0] = Dx11RenderingDevice.CompressUvw(position, textureScaling, Vector2.Abs(roomGeometry.VertexEditorUVs[i * 3 + 0]) * (image.Size - VectorInt2.One) + new Vector2(0.5f), (uint)texture.BlendMode);
                                uvwAndBlendModes[i * 3 + 1] = Dx11RenderingDevice.CompressUvw(position, textureScaling, Vector2.Abs(roomGeometry.VertexEditorUVs[i * 3 + 1]) * (image.Size - VectorInt2.One) + new Vector2(0.5f), (uint)texture.BlendMode);
                                uvwAndBlendModes[i * 3 + 2] = Dx11RenderingDevice.CompressUvw(position, textureScaling, Vector2.Abs(roomGeometry.VertexEditorUVs[i * 3 + 2]) * (image.Size - VectorInt2.One) + new Vector2(0.5f), (uint)texture.BlendMode);
                            }
                            else if (texture.TriangleCoordsOutOfBounds)
                            { // Texture is available but coordinates are ouf of bounds
                                ImageC     image    = Dx11RenderingDevice.TextureCoordOutOfBounds;
                                VectorInt3 position = TextureAllocator.Get(image);
                                uvwAndBlendModes[i * 3 + 0] = Dx11RenderingDevice.CompressUvw(position, textureScaling, Vector2.Abs(roomGeometry.VertexEditorUVs[i * 3 + 0]) * (image.Size - VectorInt2.One) + new Vector2(0.5f), (uint)texture.BlendMode);
                                uvwAndBlendModes[i * 3 + 1] = Dx11RenderingDevice.CompressUvw(position, textureScaling, Vector2.Abs(roomGeometry.VertexEditorUVs[i * 3 + 1]) * (image.Size - VectorInt2.One) + new Vector2(0.5f), (uint)texture.BlendMode);
                                uvwAndBlendModes[i * 3 + 2] = Dx11RenderingDevice.CompressUvw(position, textureScaling, Vector2.Abs(roomGeometry.VertexEditorUVs[i * 3 + 2]) * (image.Size - VectorInt2.One) + new Vector2(0.5f), (uint)texture.BlendMode);
                            }
                            else if (!texture.ParentArea.IsZero && !texture.ParentArea.Intersects(texture.GetRect()))
                            { // Texture is available but coordinates are ouf of bounds
                                ImageC     image    = Dx11RenderingDevice.TextureCoordOutOfBounds;
                                VectorInt3 position = TextureAllocator.Get(image);
                                uvwAndBlendModes[i * 3 + 0] = Dx11RenderingDevice.CompressUvw(position, textureScaling, Vector2.Abs(roomGeometry.VertexEditorUVs[i * 3 + 0]) * (image.Size - VectorInt2.One) + new Vector2(0.5f), (uint)texture.BlendMode);
                                uvwAndBlendModes[i * 3 + 1] = Dx11RenderingDevice.CompressUvw(position, textureScaling, Vector2.Abs(roomGeometry.VertexEditorUVs[i * 3 + 1]) * (image.Size - VectorInt2.One) + new Vector2(0.5f), (uint)texture.BlendMode);
                                uvwAndBlendModes[i * 3 + 2] = Dx11RenderingDevice.CompressUvw(position, textureScaling, Vector2.Abs(roomGeometry.VertexEditorUVs[i * 3 + 2]) * (image.Size - VectorInt2.One) + new Vector2(0.5f), (uint)texture.BlendMode);
                            }
                            else
                            { // Texture is available
                                VectorInt3 position = TextureAllocator.GetForTriangle(texture);
                                uvwAndBlendModes[i * 3 + 0] = Dx11RenderingDevice.CompressUvw(position, textureScaling, texture.TexCoord0, (uint)texture.BlendMode);
                                uvwAndBlendModes[i * 3 + 1] = Dx11RenderingDevice.CompressUvw(position, textureScaling, texture.TexCoord1, (uint)texture.BlendMode);
                                uvwAndBlendModes[i * 3 + 2] = Dx11RenderingDevice.CompressUvw(position, textureScaling, texture.TexCoord2, (uint)texture.BlendMode);
                            }

                            // Duplicate double sided triangles
                            if (texture.DoubleSided)
                            {
                                positions[doubleSidedVertexIndex]                  = positions[i * 3 + 2];
                                colors[doubleSidedVertexIndex]                     = colors[i * 3 + 2];
                                overlays[doubleSidedVertexIndex]                   = overlays[i * 3 + 2];
                                uvwAndBlendModes[doubleSidedVertexIndex]           = uvwAndBlendModes[i * 3 + 2];
                                editorUVAndSectorTexture[doubleSidedVertexIndex++] = editorUVAndSectorTexture[i * 3 + 2];

                                positions[doubleSidedVertexIndex]                  = positions[i * 3 + 1];
                                colors[doubleSidedVertexIndex]                     = colors[i * 3 + 1];
                                overlays[doubleSidedVertexIndex]                   = overlays[i * 3 + 1];
                                uvwAndBlendModes[doubleSidedVertexIndex]           = uvwAndBlendModes[i * 3 + 1];
                                editorUVAndSectorTexture[doubleSidedVertexIndex++] = editorUVAndSectorTexture[i * 3 + 1];

                                positions[doubleSidedVertexIndex]                  = positions[i * 3 + 0];
                                colors[doubleSidedVertexIndex]                     = colors[i * 3 + 0];
                                overlays[doubleSidedVertexIndex]                   = overlays[i * 3 + 0];
                                uvwAndBlendModes[doubleSidedVertexIndex]           = uvwAndBlendModes[i * 3 + 0];
                                editorUVAndSectorTexture[doubleSidedVertexIndex++] = editorUVAndSectorTexture[i * 3 + 0];
                            }
                        }
                    }
                    if (doubleSidedVertexIndex != vertexCount)
                    {
                        throw new ArgumentException("Double sided triangle count of RoomGeometry is wrong!");
                    }

                    // Retry texturing once at max
                    if (TexturesInvalidated && !TexturesInvalidatedRetried)
                    {
                        TexturesInvalidatedRetried = true;
                        goto RetryTexturing;
                    }
                }

                // Create GPU resources
                VertexBuffer = new Buffer(device.Device, new IntPtr(data),
                                          new BufferDescription(VertexBufferSize, ResourceUsage.Immutable, BindFlags.VertexBuffer,
                                                                CpuAccessFlags.None, ResourceOptionFlags.None, 0));
                VertexBufferBindings = new VertexBufferBinding[] {
                    new VertexBufferBinding(VertexBuffer, sizeof(Vector3), (int)((byte *)positions - data)),
                    new VertexBufferBinding(VertexBuffer, sizeof(uint), (int)((byte *)colors - data)),
                    new VertexBufferBinding(VertexBuffer, sizeof(uint), (int)((byte *)overlays - data)),
                    new VertexBufferBinding(VertexBuffer, sizeof(ulong), (int)((byte *)uvwAndBlendModes - data)),
                    new VertexBufferBinding(VertexBuffer, sizeof(uint), (int)((byte *)editorUVAndSectorTexture - data))
                };
                VertexBuffer.SetDebugName("Room " + (description.Room.Name ?? ""));
            }

            TextureAllocator.GarbageCollectionCollectEvent.Add(GarbageCollectTexture);
        }
Beispiel #8
0
        public override unsafe void RenderGlyphs(RenderingTextureAllocator textureAllocator, List <RenderingFont.GlyphRenderInfo> glyphRenderInfos, List <RectangleInt2> overlays)
        {
            Vector2 posScaling     = new Vector2(1.0f) / (Size / 2); // Divide the integer coordinates to avoid pixel mishmash.
            Vector2 posOffset      = VectorInt2.FromRounded(posScaling * 0.5f);
            Vector2 textureScaling = new Vector2(16777216.0f) / new Vector2(textureAllocator.Size.X, textureAllocator.Size.Y);

            // Build vertex buffer
            int vertexCount = glyphRenderInfos.Count * 6 + overlays.Count * 6;
            int bufferSize  = vertexCount * (sizeof(Vector2) + sizeof(ulong));

            fixed(byte *data = new byte[bufferSize])
            {
                Vector2 *positions = (Vector2 *)(data);
                ulong *  uvws      = (ulong *)(data + vertexCount * sizeof(Vector2));

                // Setup vertices
                int c = 0;

                for (int i = 0; i < overlays.Count; ++i, ++c)
                {
                    var     overlay  = overlays[i];
                    Vector2 posStart = overlay.Start * posScaling + posOffset;
                    Vector2 posEnd   = (overlay.End - new Vector2(1)) * posScaling + posOffset;

                    positions[c * 6 + 0] = new Vector2(posStart.X, posStart.Y);
                    positions[c * 6 + 2] = positions[c * 6 + 3] = new Vector2(posEnd.X, posStart.Y);
                    positions[c * 6 + 1] = positions[c * 6 + 4] = new Vector2(posStart.X, posEnd.Y);
                    positions[c * 6 + 5] = new Vector2(posEnd.X, posEnd.Y);

                    uvws[c * 6 + 2]         = uvws[c * 6 + 3] =
                        uvws[c * 6 + 1]     = uvws[c * 6 + 4] =
                            uvws[c * 6 + 5] = uvws[c * 6 + 0] = Dx11RenderingDevice.CompressUvw(VectorInt3.Zero, Vector2.Zero, Vector2.Zero, 1);
                }

                for (int i = 0; i < glyphRenderInfos.Count; ++i, ++c)
                {
                    RenderingFont.GlyphRenderInfo info = glyphRenderInfos[i];
                    Vector2 posStart = info.PosStart * posScaling + posOffset;
                    Vector2 posEnd   = (info.PosEnd - new Vector2(1)) * posScaling + posOffset;

                    positions[c * 6 + 0] = new Vector2(posStart.X, posStart.Y);
                    positions[c * 6 + 2] = positions[c * 6 + 3] = new Vector2(posEnd.X, posStart.Y);
                    positions[c * 6 + 1] = positions[c * 6 + 4] = new Vector2(posStart.X, posEnd.Y);
                    positions[c * 6 + 5] = new Vector2(posEnd.X, posEnd.Y);

                    uvws[c * 6 + 0] = Dx11RenderingDevice.CompressUvw(info.TexStart, textureScaling, new Vector2(0.5f, 0.5f));
                    uvws[c * 6 + 2] = uvws[c * 6 + 3] = Dx11RenderingDevice.CompressUvw(info.TexStart, textureScaling, new Vector2(info.TexSize.X - 0.5f, 0.5f));
                    uvws[c * 6 + 1] = uvws[c * 6 + 4] = Dx11RenderingDevice.CompressUvw(info.TexStart, textureScaling, new Vector2(0.5f, info.TexSize.Y - 0.5f));
                    uvws[c * 6 + 5] = Dx11RenderingDevice.CompressUvw(info.TexStart, textureScaling, new Vector2(info.TexSize.X - 0.5f, info.TexSize.Y - 0.5f));
                }

                // Create GPU resources
                using (var VertexBuffer = new Buffer(Device.Device, new IntPtr(data),
                                                     new BufferDescription(bufferSize, ResourceUsage.Immutable, BindFlags.VertexBuffer,
                                                                           CpuAccessFlags.None, ResourceOptionFlags.None, 0)))
                {
                    var VertexBufferBindings = new VertexBufferBinding[] {
                        new VertexBufferBinding(VertexBuffer, sizeof(Vector2), (int)((byte *)positions - data)),
                        new VertexBufferBinding(VertexBuffer, sizeof(ulong), (int)((byte *)uvws - data))
                    };

                    // Render
                    Bind();
                    Device.TextShader.Apply(Device.Context);
                    Device.Context.PixelShader.SetSampler(0, Device.SamplerDefault);
                    Device.Context.PixelShader.SetShaderResources(0, ((Dx11RenderingTextureAllocator)(textureAllocator)).TextureView);
                    Device.Context.InputAssembler.SetVertexBuffers(0, VertexBufferBindings);
                    Device.Context.OutputMerger.SetDepthStencilState(Device.DepthStencilNoZBuffer);

                    // Render
                    Device.Context.Draw(vertexCount, 0);

                    // Reset state
                    Device.Context.OutputMerger.SetDepthStencilState(Device.DepthStencilDefault);
                }
            }
        }
Beispiel #9
0
 public Dx11RenderingStateBuffer(Dx11RenderingDevice device)
 {
     Context        = device.Context;
     ConstantBuffer = new Buffer(device.Device, Size, ResourceUsage.Default,
                                 BindFlags.ConstantBuffer, CpuAccessFlags.None, ResourceOptionFlags.None, 0);
 }