private void AddEntry(PrimitiveEntry entry, ref int index) { var halfPoint = new Vector2(0.5f, 0.5f); int vertexCount = 0; switch (entry.Type) { case PrimitiveType.Points: vertexCount = 1; break; case PrimitiveType.Lines: vertexCount = 2; break; case PrimitiveType.Quads: vertexCount = 8; break; case PrimitiveType.FilledQuads: vertexCount = 6; break; case PrimitiveType.Circles: vertexCount = 2 * GetCircleEdges(entry.Circle.Radius); break; case PrimitiveType.FilledCircles: vertexCount = 3 * GetCircleEdges(entry.Circle.Radius); break; case PrimitiveType.Polygon: { if (entry.Polygon.Count < 2) { return; } vertexCount = entry.Polygon.Count * 2; } break; } var vertices = GetVertices(index + vertexCount); switch (entry.Type) { case PrimitiveType.Points: { vertices[index].Position = entry.Point + halfPoint; vertices[index].Color = entry.Color; } break; case PrimitiveType.Lines: { vertices[index + 0].Position = entry.Line.Start + halfPoint; vertices[index + 1].Position = entry.Line.End + halfPoint; vertices[index + 0].Color = entry.Color; vertices[index + 1].Color = entry.Color; } break; case PrimitiveType.Quads: { vertices[index + 0].Position.X = entry.Rect.X + halfPoint.X; vertices[index + 0].Position.Y = entry.Rect.Y + halfPoint.Y; vertices[index + 1].Position.X = entry.Rect.X + halfPoint.X; vertices[index + 1].Position.Y = entry.Rect.Y + entry.Rect.Height - 1.0f + halfPoint.Y; vertices[index + 2].Position.X = vertices[index + 1].Position.X; vertices[index + 2].Position.Y = vertices[index + 1].Position.Y; vertices[index + 3].Position.X = entry.Rect.X + entry.Rect.Width - 1.0f + halfPoint.X; vertices[index + 3].Position.Y = entry.Rect.Y + entry.Rect.Height - 1.0f + halfPoint.Y; vertices[index + 4].Position.X = vertices[index + 3].Position.X; vertices[index + 4].Position.Y = vertices[index + 3].Position.Y; vertices[index + 5].Position.X = entry.Rect.X + entry.Rect.Width - 1.0f + halfPoint.X; vertices[index + 5].Position.Y = entry.Rect.Y + halfPoint.Y; vertices[index + 6].Position.X = vertices[index + 5].Position.X; vertices[index + 6].Position.Y = vertices[index + 5].Position.Y; vertices[index + 7].Position.X = vertices[index + 0].Position.X; vertices[index + 7].Position.Y = vertices[index + 0].Position.Y; vertices[index + 0].Color = entry.Color; vertices[index + 1].Color = entry.Color; vertices[index + 2].Color = entry.Color; vertices[index + 3].Color = entry.Color; vertices[index + 4].Color = entry.Color; vertices[index + 5].Color = entry.Color; vertices[index + 6].Color = entry.Color; vertices[index + 7].Color = entry.Color; } break; case PrimitiveType.Circles: { int edges = vertexCount / 2; vertices[index].Position = new Vector2(entry.Circle.Center.X + entry.Circle.Radius + halfPoint.X, entry.Circle.Center.Y + halfPoint.Y); vertices[index].Color = entry.Color; for (int i = 1; i < edges; i++) { float a = ((float)i / edges) * MathTools.TwoPi; var p = new Vector2(entry.Circle.Center.X + entry.Circle.Radius * (float)Math.Cos(a), entry.Circle.Center.Y + entry.Circle.Radius * (float)Math.Sin(a)); var v = new Vertex2Color(p + halfPoint, entry.Color); vertices[index + i * 2 - 1] = v; vertices[index + i * 2] = v; } vertices[index + edges * 2 - 1] = vertices[index]; } break; case PrimitiveType.Polygon: { int edges = vertexCount / 2; vertices[index] = new Vertex2Color(entry.Polygon[0] + halfPoint, entry.Color); for (int i = 1; i < edges; i++) { var p = entry.Polygon[i]; var v = new Vertex2Color(p + halfPoint, entry.Color); vertices[index + i * 2 - 1] = v; vertices[index + i * 2] = v; } vertices[index + edges * 2 - 1] = vertices[index]; } break; case PrimitiveType.FilledQuads: { vertices[index + 0].Position.X = entry.Rect.X + halfPoint.X; vertices[index + 0].Position.Y = entry.Rect.Y + halfPoint.Y; vertices[index + 1].Position.X = entry.Rect.X + halfPoint.X; vertices[index + 1].Position.Y = entry.Rect.Y + entry.Rect.Height - 1.0f + halfPoint.Y; vertices[index + 2].Position.X = entry.Rect.X + entry.Rect.Width - 1.0f + halfPoint.X; vertices[index + 2].Position.Y = entry.Rect.Y + halfPoint.Y; vertices[index + 3].Position = vertices[index + 2].Position; vertices[index + 4].Position = vertices[index + 1].Position; vertices[index + 5].Position.X = entry.Rect.X + entry.Rect.Width - 1.0f + halfPoint.X; vertices[index + 5].Position.Y = entry.Rect.Y + entry.Rect.Height - 1.0f + halfPoint.Y; for (int i = 0; i < vertexCount; i++) { vertices[index + i].Color = entry.Color; } } break; case PrimitiveType.FilledCircles: { int edges = vertexCount / 3; var center = new Vertex2Color(entry.Circle.Center + halfPoint, entry.Color); vertices[index] = new Vertex2Color(new Vector2(entry.Circle.Center.X + entry.Circle.Radius + halfPoint.X, entry.Circle.Center.Y + halfPoint.Y), entry.Color); vertices[index + 1] = center; for (int i = 1; i < edges; i++) { float a = ((float)i / edges) * MathTools.TwoPi; var p = new Vector2(entry.Circle.Center.X + entry.Circle.Radius * (float)Math.Cos(a), entry.Circle.Center.Y + entry.Circle.Radius * (float)Math.Sin(a)); var v = new Vertex2Color(p + halfPoint, entry.Color); vertices[index + i * 3 - 1] = v; vertices[index + i * 3] = v; vertices[index + i * 3 + 1] = center; } vertices[index + edges * 3 - 1] = vertices[index]; } break; } index += vertexCount; }
public void Render(RenderQueue.Batch renderBatch) { var batch = (Batch)renderBatch; var entries = batch.Entries; if (entries.Count == 0) { return; } RenderHelpers.SetBlendMode(blendMode); GL.Disable(EnableCap.DepthTest); GL.Disable(EnableCap.CullFace); currentEffect.Projection = Projection ?? CurrentContext.ActiveScreen.DefaultProjection; currentEffect.View = transform; currentEffect.Enable(); GL.BindBuffer(BufferTarget.ArrayBuffer, vertexBufferObjects[0]); GL.VertexAttribPointer(currentEffect.VertexAttribute, 2, VertexAttribPointerType.Float, false, Vertex2Color.GetSize(), 0); if (currentEffect.ColorAttribute.HasValue) { GL.VertexAttribPointer(currentEffect.ColorAttribute.Value, 4, VertexAttribPointerType.UnsignedByte, true, Vertex2Color.GetSize(), 2 * sizeof(float)); } for (int entryIndex = 0; entryIndex < entries.Count;) { var startingEntry = entries[entryIndex]; var mode = GetMode(startingEntry); int index = 0; AddEntry(startingEntry, ref index); for (int nextIndex = entryIndex + 1; nextIndex < entries.Count; ++nextIndex) { var nextEntry = entries[nextIndex]; if (GetMode(nextEntry) == mode) { AddEntry(nextEntry, ref index); entryIndex++; } else { break; } } if (index > 0) { GL.BufferData(BufferTarget.ArrayBuffer, (IntPtr)(index * Vertex2Color.GetSize()), vertexStorage, BufferUsageHint.DynamicDraw); GL.DrawArrays(mode, 0, index); } entryIndex++; } entries.Clear(); currentEffect.Disable(); GL.BindBuffer(BufferTarget.ArrayBuffer, 0); // This group is done, recycle it to the pool batchPool.Delete(batch); }