Пример #1
0
            public NativeBatch(ISoftwareBuffer softwareBuffer, TextureSet textureSet, int localIndexOffset, int localVertexOffset, int vertexCount)
            {
                SoftwareBuffer = softwareBuffer;
                TextureSet     = textureSet;

                LocalIndexOffset  = localIndexOffset;
                LocalVertexOffset = localVertexOffset;
                VertexCount       = vertexCount;
            }
Пример #2
0
        public BitmapDrawCall(Texture2D texture, Vector2 position, Bounds textureRegion, Color color, Vector2 scale, Vector2 origin, float rotation)
        {
            if (texture == null)
            {
                throw new ArgumentNullException("texture");
            }
            else if (texture.IsDisposed)
            {
                throw new ObjectDisposedException("texture");
            }

            Textures      = new TextureSet(texture);
            Position      = position;
            TextureRegion = textureRegion;
            MultiplyColor = color;
            AddColor      = new Color(0, 0, 0, 0);
            Scale         = scale;
            Origin        = origin;
            Rotation      = rotation;

            SortKey = 0;
        }
Пример #3
0
 public bool Equals(ref TextureSet rhs)
 {
     return((HashCode == rhs.HashCode) && (Texture1 == rhs.Texture1) && (Texture2 == rhs.Texture2));
 }
Пример #4
0
        public override void Issue(DeviceManager manager)
        {
            if (IsCombined)
            {
                throw new InvalidOperationException("Batch was combined into another batch");
            }

            if (_DrawCalls.Count == 0)
            {
                return;
            }

            if (_Prepared == false)
            {
                throw new InvalidOperationException("Not prepared");
            }

            if (_BufferGenerator == null)
            {
                throw new InvalidOperationException("Already issued");
            }

            var device = manager.Device;

            IHardwareBuffer previousHardwareBuffer = null;

            // if (RenderTrace.EnableTracing)
            //    RenderTrace.ImmediateMarker("BitmapBatch.Issue(layer={0}, count={1})", Layer, _DrawCalls.Count);

            using (manager.ApplyMaterial(Material)) {
                TextureSet currentTexture = new TextureSet();
                var        paramSize      = manager.CurrentParameters.BitmapTextureSize;
                var        paramHalfTexel = manager.CurrentParameters.HalfTexel;

                foreach (var nb in _NativeBatches)
                {
                    if (nb.TextureSet != currentTexture)
                    {
                        currentTexture = nb.TextureSet;
                        var tex1 = currentTexture.Texture1;

                        device.Textures[0]      = tex1;
                        device.Textures[1]      = currentTexture.Texture2;
                        device.SamplerStates[0] = SamplerState;
                        device.SamplerStates[1] = SamplerState2;

                        var vSize = new Vector2(tex1.Width, tex1.Height);
                        paramSize.SetValue(vSize);
#if !SDL2
                        // This is only ever used by Blur, which is never used -flibit
                        paramHalfTexel.SetValue(new Vector2(1.0f / vSize.X, 1.0f / vSize.Y) * 0.5f);
#endif

                        manager.CurrentMaterial.Flush();
                    }

                    if (UseZBuffer)
                    {
                        var dss = device.DepthStencilState;
                        if (dss.DepthBufferEnable == false)
                        {
                            throw new InvalidOperationException("UseZBuffer set to true but depth buffer is disabled");
                        }
                    }

                    var swb = nb.SoftwareBuffer;
                    var hwb = swb.HardwareBuffer;
                    if (previousHardwareBuffer != hwb)
                    {
                        if (previousHardwareBuffer != null)
                        {
                            previousHardwareBuffer.SetInactive(device);
                        }

                        hwb.SetActive(device);
                        previousHardwareBuffer = hwb;
                    }

#if PSM
                    // MonoGame and PSM are both retarded.
                    device.ApplyState(false);
                    device.Textures.SetTextures(device);
                    device.SamplerStates.SetSamplers(device);

                    device._graphics.DrawArrays(
                        Sce.PlayStation.Core.Graphics.DrawMode.Triangles,
                        nb.IndexOffset, (nb.VertexCount / 4) * 6
                        );
#else
                    device.DrawIndexedPrimitives(
                        PrimitiveType.TriangleList, 0,
                        swb.HardwareVertexOffset + nb.LocalVertexOffset,
                        nb.VertexCount,
                        swb.HardwareIndexOffset + nb.LocalIndexOffset,
                        nb.VertexCount / 2
                        );
#endif
                }

                if (previousHardwareBuffer != null)
                {
                    previousHardwareBuffer.SetInactive(device);
                }
            }

            _BufferGenerator = null;

            base.Issue(manager);
        }
Пример #5
0
        private unsafe void FillOneSoftwareBuffer(BitmapDrawCall[] drawCalls, ref int drawCallsPrepared, int count)
        {
#endif
            int totalVertCount = 0;
            int vertCount = 0, vertOffset = 0;
            int indexCount = 0, indexOffset = 0;
            int nativeBatchSizeLimit = NativeBatchSize * 4;
            int vertexWritePosition = 0, indexWritePosition = 0;

            TextureSet   currentTextures = new TextureSet();
            BitmapVertex vertex          = new BitmapVertex();

            var remainingDrawCalls = (count - drawCallsPrepared);
            var remainingVertices  = remainingDrawCalls * 4;

            int nativeBatchSize = Math.Min(nativeBatchSizeLimit, remainingVertices);
            var softwareBuffer  = _BufferGenerator.Allocate(nativeBatchSize, (nativeBatchSize / 4) * 6);

            ushort indexBase = (ushort)softwareBuffer.HardwareVertexOffset;

            float zBufferFactor = UseZBuffer ? 1.0f : 0.0f;

#if !PSM
            fixed(BitmapVertex *pVertices = &softwareBuffer.Vertices.Array[softwareBuffer.Vertices.Offset])
            fixed(ushort *pIndices = &softwareBuffer.Indices.Array[softwareBuffer.Indices.Offset])
#else
            var indexArray = softwareBuffer.Indices.Array;

            var indexArrayOffset = softwareBuffer.Indices.Offset;
#endif
            for (int i = drawCallsPrepared; i < count; i++)
            {
                if (totalVertCount >= nativeBatchSizeLimit)
                {
                    break;
                }

                var call = drawCalls[i];

#if PSM
                // HACK: PSM render targets have an inverted Y axis, so if the bitmap being drawn is a render target,
                //   flip it vertically.
                if (call.Textures.Texture1 is RenderTarget2D)
                {
                    call.Mirror(false, true);
                }
#endif

                bool texturesEqual = call.Textures.Equals(ref currentTextures);

                if (!texturesEqual)
                {
                    if (vertCount > 0)
                    {
                        _NativeBatches.Add(new NativeBatch(
                                               softwareBuffer, currentTextures,
                                               indexOffset,
                                               vertOffset,
                                               vertCount
                                               ));

                        indexOffset += indexCount;
                        vertOffset  += vertCount;
                        indexCount   = 0;
                        vertCount    = 0;
                    }

                    currentTextures = call.Textures;
                }

                vertex.Position.X = call.Position.X;
                vertex.Position.Y = call.Position.Y;
                vertex.Position.Z = call.SortKey * zBufferFactor;
                var tr = call.TextureRegion;
                vertex.TextureTopLeft     = tr.TopLeft;
                vertex.TextureBottomRight = tr.BottomRight;
                vertex.MultiplyColor      = call.MultiplyColor;
                vertex.AddColor           = call.AddColor;
                vertex.Scale    = call.Scale;
                vertex.Origin   = call.Origin;
                vertex.Rotation = call.Rotation;

#if !PSM
                for (var j = 0; j < 6; j++)
                {
                    pIndices[indexWritePosition + j] = (ushort)(indexBase + QuadIndices[j]);
                }
#else
                for (var j = 0; j < 6; j++)
                {
                    indexArray[indexArrayOffset + indexWritePosition + j] = (ushort)(indexBase + QuadIndices[j]);
                }
#endif

                indexWritePosition += 6;

                for (short j = 0; j < 4; j++)
                {
#if !PSM
                    vertex.Unused = vertex.Corner = j;
                    pVertices[vertexWritePosition + j] = vertex;
#else
                    vertex.Corner = FloatCorners[j];
                    buffers.Vertices.Array[buffers.Vertices.Offset + vertexWritePosition + j] = vertex;
#endif
                }

                vertexWritePosition += 4;
                indexBase           += 4;

                totalVertCount += 4;
                vertCount      += 4;
                indexCount     += 6;

                drawCallsPrepared += 1;
            }

            if (indexWritePosition > softwareBuffer.Indices.Count)
            {
                throw new InvalidOperationException("Wrote too many indices");
            }
            else if (vertexWritePosition > softwareBuffer.Vertices.Count)
            {
                throw new InvalidOperationException("Wrote too many vertices");
            }

            if (vertCount > 0)
            {
                _NativeBatches.Add(new NativeBatch(
                                       softwareBuffer, currentTextures,
                                       indexOffset,
                                       vertOffset,
                                       vertCount
                                       ));
            }
        }