summaryrefslogtreecommitdiff
path: root/Xamarin.Forms.Platform.iOS/Renderers/OpenGLViewRenderer.cs
diff options
context:
space:
mode:
Diffstat (limited to 'Xamarin.Forms.Platform.iOS/Renderers/OpenGLViewRenderer.cs')
-rw-r--r--Xamarin.Forms.Platform.iOS/Renderers/OpenGLViewRenderer.cs122
1 files changed, 122 insertions, 0 deletions
diff --git a/Xamarin.Forms.Platform.iOS/Renderers/OpenGLViewRenderer.cs b/Xamarin.Forms.Platform.iOS/Renderers/OpenGLViewRenderer.cs
new file mode 100644
index 00000000..84c67744
--- /dev/null
+++ b/Xamarin.Forms.Platform.iOS/Renderers/OpenGLViewRenderer.cs
@@ -0,0 +1,122 @@
+using System;
+using System.Drawing;
+using System.ComponentModel;
+#if __UNIFIED__
+using GLKit;
+using OpenGLES;
+using Foundation;
+using CoreAnimation;
+#else
+using MonoTouch.GLKit;
+using MonoTouch.OpenGLES;
+using MonoTouch.Foundation;
+using MonoTouch.CoreAnimation;
+#endif
+#if __UNIFIED__
+using RectangleF = CoreGraphics.CGRect;
+using SizeF = CoreGraphics.CGSize;
+using PointF = CoreGraphics.CGPoint;
+
+#else
+using nfloat=System.Single;
+using nint=System.Int32;
+using nuint=System.UInt32;
+#endif
+
+namespace Xamarin.Forms.Platform.iOS
+{
+ internal class OpenGLViewRenderer : ViewRenderer<OpenGLView, GLKView>
+ {
+ CADisplayLink _displayLink;
+
+ public void Display(object sender, EventArgs eventArgs)
+ {
+ if (Element.HasRenderLoop)
+ return;
+ SetupRenderLoop(true);
+ }
+
+ protected override void Dispose(bool disposing)
+ {
+ if (_displayLink != null)
+ {
+ _displayLink.Invalidate();
+ _displayLink.Dispose();
+ _displayLink = null;
+
+ if (Element != null)
+ ((IOpenGlViewController)Element).DisplayRequested -= Display;
+ }
+
+ base.Dispose(disposing);
+ }
+
+ protected override void OnElementChanged(ElementChangedEventArgs<OpenGLView> e)
+ {
+ if (e.OldElement != null)
+ ((IOpenGlViewController)e.OldElement).DisplayRequested -= Display;
+
+ if (e.NewElement != null)
+ {
+ var context = new EAGLContext(EAGLRenderingAPI.OpenGLES2);
+ var glkView = new GLKView(RectangleF.Empty) { Context = context, DrawableDepthFormat = GLKViewDrawableDepthFormat.Format24, Delegate = new Delegate(e.NewElement) };
+ SetNativeControl(glkView);
+
+ ((IOpenGlViewController)e.NewElement).DisplayRequested += Display;
+
+ SetupRenderLoop(false);
+ }
+
+ base.OnElementChanged(e);
+ }
+
+ protected override void OnElementPropertyChanged(object sender, PropertyChangedEventArgs e)
+ {
+ base.OnElementPropertyChanged(sender, e);
+
+ if (e.PropertyName == OpenGLView.HasRenderLoopProperty.PropertyName)
+ SetupRenderLoop(false);
+ }
+
+ void SetupRenderLoop(bool oneShot)
+ {
+ if (_displayLink != null)
+ return;
+ if (!oneShot && !Element.HasRenderLoop)
+ return;
+
+ _displayLink = CADisplayLink.Create(() =>
+ {
+ var control = Control;
+ var model = Element;
+ if (control != null)
+ control.Display();
+ if (control == null || model == null || !model.HasRenderLoop)
+ {
+ _displayLink.Invalidate();
+ _displayLink.Dispose();
+ _displayLink = null;
+ }
+ });
+ _displayLink.AddToRunLoop(NSRunLoop.Current, NSRunLoop.NSDefaultRunLoopMode);
+ }
+
+ class Delegate : GLKViewDelegate
+ {
+ readonly OpenGLView _model;
+
+ public Delegate(OpenGLView model)
+ {
+ _model = model;
+ }
+
+ public override void DrawInRect(GLKView view, RectangleF rect)
+ {
+ var onDisplay = _model.OnDisplay;
+ if (onDisplay == null)
+ return;
+ onDisplay(rect.ToRectangle());
+ }
+ }
+ }
+} \ No newline at end of file