2 using System.ComponentModel;
3 using System.Runtime.InteropServices;
4 using System.Collections.Generic;
5 using System.Collections.ObjectModel;
6 using System.Diagnostics.CodeAnalysis;
8 namespace Tizen.NUI.BaseComponents
11 /// DirectRenderingGLView allows drawing with OpenGL. You can render to a Window directly.
12 /// DirectRenderingGLView creates a context.
14 /// <since_tizen> 11 </since_tizen>
15 [EditorBrowsable(EditorBrowsableState.Never)]
16 public class DirectRenderingGLView : View
19 /// The parameter of the RenderFrame Callback.
20 /// It has data to render directly.
22 [SuppressMessage("Microsoft.Design", "CA1034:NestedTypesShouldNotBeVisible")]
23 public class RenderCallbackInput
28 Rectangle clippingBox;
29 ReadOnlyCollection<int> textureBindings;
31 public RenderCallbackInput(Matrix mvp, Matrix projection, Size2D size, Rectangle clippingBox, int[] textureBindings)
34 this.projection = projection;
36 this.clippingBox = clippingBox;
37 this.textureBindings = new ReadOnlyCollection<int>(textureBindings);
51 public Matrix Projection
53 get { return projection; }
57 /// The size of the DirectRenderingGLView
65 /// The area of DirectRenderingGLView. You can use this for glScissor()
67 public Rectangle ClippingBox
69 get { return clippingBox; }
75 public ReadOnlyCollection<int> TextureBindings
77 get { return textureBindings; }
81 private GLInitializeDelegate glInitializeCallback;
82 private GLRenderFrameDelegate glRenderFrameCallback;
83 private GLTerminateDelegate glTerminateCallback;
84 private InternalGLRenderFrameDelegate internalRenderFrameCallback;
87 /// Type of callback to initialize OpenGLES.
89 public delegate void GLInitializeDelegate();
92 /// Type of callback to render the frame with OpenGLES APIs.
93 /// If the return value of this callback is not 0, the eglSwapBuffers() will be called.
95 /// <returns>The return value is not 0, the eglSwapBuffers() will be called.</returns>
96 public delegate int GLRenderFrameDelegate(in RenderCallbackInput input);
98 private delegate int InternalGLRenderFrameDelegate(global::System.IntPtr cPtr);
101 /// Type of callback to clean up GL resource.
103 public delegate void GLTerminateDelegate();
105 internal DirectRenderingGLView(global::System.IntPtr cPtr, bool cMemoryOwn) : base(cPtr, cMemoryOwn)
110 /// Creates an initialized DirectRenderingGLView.
112 /// <param name="colorFormat">The format of the color buffer</param>
113 public DirectRenderingGLView(ColorFormat colorFormat) : this(Interop.GLView.New(0, (int)colorFormat), true)
115 if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
119 /// Creates an initialized DirectRenderingGLView.
121 /// <param name="colorFormat">The format of the color buffer</param>
122 /// <param name="backendMode">The backend mode</param>
123 [EditorBrowsable(EditorBrowsableState.Never)]
124 public DirectRenderingGLView(ColorFormat colorFormat, BackendMode backendMode) : this(Interop.GLView.New((int)backendMode, (int)colorFormat), true)
126 if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
130 /// Enumeration for the color format of the color buffer
132 public enum ColorFormat
135 /// 8 red bits, 8 green bits, 8 blue bits
140 /// 8 red bits, 8 green bits, 8 blue bits, alpha 8 bits
146 /// Enumeration for backend mode
148 [EditorBrowsable(EditorBrowsableState.Never)]
149 public enum BackendMode
152 /// DirectRendering mode executes GL code within DALi graphics
153 /// pipeline but creates isolated context hence it doesn't alter any
154 /// DALi rendering state. When Renderer is about to be drawn, the callback
155 /// will be executed and the custom code "injected" into the pipeline.
156 /// This allows rendering directly to the surface rather than offscreen.
161 /// DirectRenderingThread mode executes GL code on separate thread
162 /// and then blits the result within DALi graphics commands stream.
163 /// The mode is logically compatible with the EglImageOffscreenRendering.
165 DirectRenderingThread,
168 /// EglImageOffscreenRendering mode executes GL code in own thread
169 /// and renders to the offscreen NativeImage (EGL) buffer. This backend
170 /// will render in parallel but has higher memory footprint and may suffer
171 /// performance issues due to using EGL image.
173 EglImageOffscreenRendering,
176 /// UnsafeDirectRendering mode executes GL code within DALi graphics
177 /// pipeline WITHOUT isolating the GL context so should be used with caution!
178 /// The custom rendering code is executed within current window context and
179 /// may alter the GL state. This mode is considered unsafe and should be used
180 /// only when drawing on main GL context is necessary!
182 /// When Renderer is about to be drawn, the callback
183 /// will be executed and the custom code "injected" into the pipeline.
184 /// This allows rendering directly to the surface rather than offscreen.
186 UnsafeDirectRendering
190 /// Gets or sets the rendering mode of the DirectRenderingGLView.
192 public GLRenderingMode RenderingMode
194 [SuppressMessage("Microsoft.Design", "CA1065:DoNotRaiseExceptionsInUnexpectedLocations", Justification = "SWIG boilerplate, no exceptions are expected")]
197 GLRenderingMode ret = (GLRenderingMode)Interop.GLView.GlViewGetRenderingMode(SwigCPtr);
198 if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
203 Interop.GLView.GlViewSetRenderingMode(SwigCPtr, (int)value);
204 if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
209 /// Registers GL callback functions to render with OpenGL ES
211 /// <param name="glInit">The callback function for GL initialization</param>
212 /// <param name="glRenderFrame">The callback function to render the frame</param>
213 /// <param name="glTerminate">The callback function to clean up GL resources</param>
214 public void RegisterGLCallbacks(GLInitializeDelegate glInit, GLRenderFrameDelegate glRenderFrame, GLTerminateDelegate glTerminate)
216 glInitializeCallback = glInit;
217 HandleRef InitHandleRef = new HandleRef(this, Marshal.GetFunctionPointerForDelegate<Delegate>(glInitializeCallback));
219 glRenderFrameCallback = glRenderFrame;
220 internalRenderFrameCallback = OnRenderFrame;
221 HandleRef RenderHandlerRef = new HandleRef(this, Marshal.GetFunctionPointerForDelegate<Delegate>(internalRenderFrameCallback));
223 glTerminateCallback = glTerminate;
224 HandleRef TerminateHandlerRef = new HandleRef(this, Marshal.GetFunctionPointerForDelegate<Delegate>(glTerminateCallback));
226 Interop.GLView.GlViewRegisterGlCallbacks(SwigCPtr, InitHandleRef, RenderHandlerRef, TerminateHandlerRef);
228 if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
232 /// Binds textures to own context.
233 /// You can get the bind IDs in RenderCallbackInput in the glRenderFrame callback.
235 /// <param name="textures">List of Textures</param>
236 /// <exception cref="OverflowException"> Thrown when length of textures list is overflow. </exception>
237 public void BindTextureResources(List<Texture> textures)
241 if (textures != null)
243 int count = textures.Count;
246 IntPtr[] texturesArray = new IntPtr[count];
247 for (int i = 0; i < count; i++)
249 texturesArray[i] = HandleRef.ToIntPtr(Texture.getCPtr(textures[i]));
251 IntPtr unmanagedPointer = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(IntPtr)) * count);
252 Marshal.Copy(texturesArray, 0, unmanagedPointer, count);
254 Interop.GLView.GlViewBindTextureResources(SwigCPtr, unmanagedPointer, count);
255 Marshal.FreeHGlobal(unmanagedPointer);
262 /// Sets graphics configuration for the DirectRenderingGLView
264 /// <param name="depth">The flag of depth buffer. When the value is true, 24bit depth buffer is enabled.</param>
265 /// <param name="stencil">The flag of stencil. When the value is true, 8bit stencil buffer is enabled.</param>
266 /// <param name="msaa">The bit of MSAA</param>
267 /// <param name="version">The GLES version</param>
268 /// <returns>True if the config was successfully set, false otherwise.</returns>
269 public bool SetGraphicsConfig(bool depth, bool stencil, int msaa, GLESVersion version)
271 bool ret = Interop.GLView.GlViewSetGraphicsConfig(SwigCPtr, depth, stencil, msaa, (int)version);
272 if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
277 /// Renders once more, even when paused.
279 public void RenderOnce()
281 Interop.GLView.GlViewRenderOnce(SwigCPtr);
282 if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
285 private int OnRenderFrame(global::System.IntPtr cPtr)
287 if (glRenderFrameCallback != null)
289 Matrix mvp = Matrix.GetMatrixFromPtr(Interop.GLView.GlViewGetRednerCallbackInputMvp(cPtr));
290 Matrix projection = Matrix.GetMatrixFromPtr(Interop.GLView.GlViewGetRednerCallbackInputProjection(cPtr));
291 Size2D size = Size2D.GetSize2DFromPtr(Interop.GLView.GlViewGetRednerCallbackInputSize(cPtr));
292 Rectangle clippingBox = Rectangle.GetRectangleFromPtr(Interop.GLView.GlViewGetRednerCallbackInputClipplingBox(cPtr));
293 int[] textureBindings = GetTextureBindings(cPtr);
295 RenderCallbackInput input = new RenderCallbackInput(mvp, projection, size, clippingBox, textureBindings);
297 return glRenderFrameCallback(input);
302 private static int[] GetTextureBindings(global::System.IntPtr cPtr)
305 global::System.IntPtr arrayPtr = Interop.GLView.GlViewGetRednerCallbackInputTextureBindings(cPtr, ref bindingSize);
306 if (bindingSize != 0)
308 int[] result = new int[bindingSize];
309 System.Runtime.InteropServices.Marshal.Copy(arrayPtr, result, 0, bindingSize);
314 return Array.Empty<int>();