void Flush() { if (vertexCount == 0 || primitiveCount == 0) { return; } rs.Cull = false; rs.BlendMode = currentMode; rs.DepthEnabled = false; currentTexture.BindTo(0); if (currentTexture.Format == SurfaceFormat.R8) { imgShader.SetFloat(blendLocation, 1f); } else { imgShader.SetFloat(blendLocation, 0f); } var verts = new Vertex2D[vertexCount]; for (int i = 0; i < vertexCount; i++) { verts[i] = vertices[i]; } vbo.EndStreaming(vertexCount); vbo.Draw(PrimitiveTypes.TriangleList, primitiveCount); vertices = (Vertex2D *)vbo.BeginStreaming(); vertexCount = 0; primitiveCount = 0; currentTexture = null; rs.Cull = true; }
void Prepare(BlendMode mode, Texture2D tex, bool circle) { if (currentMode != mode || isCircle != circle || (currentTexture != null && (currentTexture != tex && currentTexture != dot) && tex != dot) || (primitiveCount + 2) * 3 >= MAX_INDEX || (vertexCount + 4) >= MAX_VERT) { Flush(); } if (vertices == (Vertex2D *)0) { currentMode = BlendMode.Normal; currentTexture = null; vertices = (Vertex2D *)vbo.BeginStreaming(); isCircle = false; } if (tex == dot) { currentTexture ??= tex; } else { currentTexture = tex; } currentMode = mode; isCircle = circle; }
private unsafe void PopulateVertex( Sprite *sprite, Texture <T> texture, Vertex2D *tl, Vertex2D *tr, Vertex2D *bl, Vertex2D *br) { var w = (sprite->Size.X > 0 ? sprite->Size.X : texture.Width) * sprite->Scale.X; var h = (sprite->Size.Y > 0 ? sprite->Size.Y : texture.Height) * sprite->Scale.Y; var x = sprite->Position.X - sprite->Origin.X * w; var y = sprite->Position.Y - sprite->Origin.Y * h; tl->Position.X = x; tl->Position.Y = y; tl->Color = sprite->Color.Bgra; tl->TextureCoordinate.X = texture.UvLeft; tl->TextureCoordinate.Y = texture.UvTop; tr->Position.X = x + w; tr->Position.Y = y; tr->Color = sprite->Color.Bgra; tr->TextureCoordinate.X = texture.UvRight; tr->TextureCoordinate.Y = texture.UvTop; bl->Position.X = x; bl->Position.Y = y + h; bl->Color = sprite->Color.Bgra; bl->TextureCoordinate.X = texture.UvLeft; bl->TextureCoordinate.Y = texture.UvBottom; br->Position.X = x + w; br->Position.Y = y + h; br->Color = sprite->Color.Bgra; br->TextureCoordinate.X = texture.UvRight; br->TextureCoordinate.Y = texture.UvBottom; }
public void Start(int vpWidth, int vpHeight) { if (active) { throw new InvalidOperationException("Renderer2D.Start() called without calling Renderer2D.Finish()"); } active = true; this.vpHeight = vpHeight; var mat = Matrix4x4.CreateOrthographicOffCenter(0, vpWidth, vpHeight, 0, 0, 1); imgShader.SetMatrix(imgShader.GetLocation("modelviewproj"), ref mat); currentMode = BlendMode.Normal; vertices = (Vertex2D *)vbo.BeginStreaming(); }
private unsafe void PopulateVertexWithRotationAndTransform( Sprite *sprite, Texture <T> texture, Vertex2D *tl, Vertex2D *tr, Vertex2D *bl, Vertex2D *br, Matrix3x2 transform) { var w = (sprite->Size.X > 0 ? sprite->Size.X : texture.Width) * sprite->Scale.X; var h = (sprite->Size.Y > 0 ? sprite->Size.Y : texture.Height) * sprite->Scale.Y; var x = sprite->Position.X; var y = sprite->Position.Y; var dx = -sprite->Origin.X * w; var dy = -sprite->Origin.Y * h; var radius = MathHelper.ToRadius(sprite->Rotation); var cos = Math.Cos(radius); var sin = Math.Sin(radius); tl->Position.X = (float)(x + dx * cos - dy * sin); tl->Position.Y = (float)(y + dx * sin + dy * cos); tl->Color = sprite->Color.Bgra; tl->TextureCoordinate.X = texture.UvLeft; tl->TextureCoordinate.Y = texture.UvTop; tr->Position.X = (float)(x + (dx + w) * cos - dy * sin); tr->Position.Y = (float)(y + (dx + w) * sin + dy * cos); tr->Color = sprite->Color.Bgra; tr->TextureCoordinate.X = texture.UvRight; tr->TextureCoordinate.Y = texture.UvTop; bl->Position.X = (float)(x + dx * cos - (dy + h) * sin); bl->Position.Y = (float)(y + dx * sin + (dy + h) * cos); bl->Color = sprite->Color.Bgra; bl->TextureCoordinate.X = texture.UvLeft; bl->TextureCoordinate.Y = texture.UvBottom; br->Position.X = (float)(x + (dx + w) * cos - (dy + h) * sin); br->Position.Y = (float)(y + (dx + w) * sin + (dy + h) * cos); br->Color = sprite->Color.Bgra; br->TextureCoordinate.X = texture.UvRight; br->TextureCoordinate.Y = texture.UvBottom; tl->Position = Vector2.Transform(tl->Position, transform); tr->Position = Vector2.Transform(tr->Position, transform); bl->Position = Vector2.Transform(bl->Position, transform); br->Position = Vector2.Transform(br->Position, transform); }
protected override unsafe void Draw(Vertex2D *pVertex, int vertexCount, DXTexture texture, bool isTransparent) { // TODO: texture, isTransparent commandList.SetGraphicsRootDescriptorTable(1, graphicsHost.SRVHeap.GPUDescriptorHandleForHeapStart); // Update the vertex buffer IntPtr dataBegin = vertexBuffer.Map(0); SharpDX.Utilities.CopyMemory(dataBegin, new IntPtr(pVertex), vertexCount * Vertex2D.SizeInBytes); vertexBuffer.Unmap(0); // Record the commands. commandList.SetVertexBuffer(0, vertexBufferView); // commandList.SetIndexBuffer(quadIndexBuffer.indexBufferView); // Call draw. commandList.DrawIndexedInstanced(vertexCount / 4 * 6, 1, 0, 0, 0); }
protected override unsafe void Draw(Vertex2D *pVertex, int vertexCount, int texture, bool isTransparent) { GLDebug.CheckAccess(); GL.BufferData(BufferTarget.ArrayBuffer, (IntPtr)(vertexCount * Vertex2D.SizeInBytes), (IntPtr)pVertex, BufferUsageHint.StaticDraw); GL.BindTexture(TextureTarget.Texture2D, texture); if (isTransparent) { GL.Enable(EnableCap.Blend); GL.BlendFunc(BlendingFactorSrc.One, BlendingFactorDest.OneMinusSrcAlpha); } else { GL.Disable(EnableCap.Blend); } GL.DrawElements(BeginMode.Triangles, vertexCount / 4 * 6, DrawElementsType.UnsignedShort, 0); }
void Flush() { if (vertexCount == 0 || primitiveCount == 0) { return; } rs.Cull = false; rs.BlendMode = currentMode; rs.DepthEnabled = false; currentTexture.BindTo(0); currentShader.UseProgram(); //vbo.SetData (vertices, vertexCount); vbo.EndStreaming(vertexCount); vbo.Draw(PrimitiveTypes.TriangleList, primitiveCount); vertices = (Vertex2D *)vbo.BeginStreaming(); vertexCount = 0; primitiveCount = 0; currentTexture = null; rs.Cull = true; }
public unsafe void Draw(Matrix4x4 projection, Slice <Sprite> sprites, Slice <Matrix3x2>?transforms = null) { if (sprites.Length <= 0) { return; } if (sprites.Length * 4 > _vertexData.Length) { Array.Resize(ref _vertexData, sprites.Length * 4); } fixed(ushort *pIndex = QuadListIndexData.GetIndices(sprites.Length)) fixed(Vertex2D * pVertex = _vertexData) fixed(Sprite * pSprite = &sprites.Items[sprites.Begin]) { var vertexCount = 0; var drawing = false; var isTransparent = false; var previousTexture = (Texture <T>)null; Vertex2D *vertex = pVertex; Sprite * sprite = pSprite; for (var i = 0; i < sprites.Length; i++) { var currentTexture = _textureFactory.GetTexture(sprite->Texture); if (currentTexture == null) { continue; } if (previousTexture == null) { previousTexture = currentTexture; } else if (!_equaltyComparer.Equals(currentTexture.PlatformTexture, previousTexture.PlatformTexture)) { if (!drawing) { drawing = true; BeginDraw(ref projection, pIndex, sprites.Length * 6); } Draw(pVertex, vertexCount, previousTexture.PlatformTexture, isTransparent); vertexCount = 0; vertex = pVertex; previousTexture = currentTexture; isTransparent = false; } var isSpriteTransparent = currentTexture.IsTransparent || sprite->Color.IsTransparent; isTransparent |= isSpriteTransparent; if (sprite->Rotation == 0) { if (transforms == null) { PopulateVertex(sprite, currentTexture, vertex++, vertex++, vertex++, vertex++); } else { PopulateVertexWithTransform(sprite, currentTexture, vertex++, vertex++, vertex++, vertex++, transforms.Value[i]); } } else { if (transforms == null) { PopulateVertexWithRotation(sprite, currentTexture, vertex++, vertex++, vertex++, vertex++); } else { PopulateVertexWithRotationAndTransform(sprite, currentTexture, vertex++, vertex++, vertex++, vertex++, transforms.Value[i]); } } vertexCount += 4; sprite++; } if (vertexCount > 0) { if (!drawing) { drawing = true; BeginDraw(ref projection, pIndex, sprites.Length * 6); } Draw(pVertex, vertexCount, previousTexture.PlatformTexture, isTransparent); } if (drawing) { EndDraw(); } } }
protected abstract unsafe void Draw(Vertex2D *pVertex, int vertexCount, T texture, bool isTransparent);