public NativeBatch(ISoftwareBuffer softwareBuffer, TextureSet textureSet, int localIndexOffset, int localVertexOffset, int vertexCount) { SoftwareBuffer = softwareBuffer; TextureSet = textureSet; LocalIndexOffset = localIndexOffset; LocalVertexOffset = localVertexOffset; VertexCount = vertexCount; }
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; }
public bool Equals(ref TextureSet rhs) { return((HashCode == rhs.HashCode) && (Texture1 == rhs.Texture1) && (Texture2 == rhs.Texture2)); }
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); }
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 )); } }