1 /*
2  * This file is part of gtkD.
3  *
4  * gtkD is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU Lesser General Public License
6  * as published by the Free Software Foundation; either version 3
7  * of the License, or (at your option) any later version, with
8  * some exceptions, please read the COPYING file.
9  *
10  * gtkD is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  * GNU Lesser General Public License for more details.
14  *
15  * You should have received a copy of the GNU Lesser General Public License
16  * along with gtkD; if not, write to the Free Software
17  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110, USA
18  */
19 
20 // generated automatically - do not change
21 // find conversion definition on APILookup.txt
22 // implement new conversion functionalities on the wrap.utils pakage
23 
24 
25 module gtk.GLArea;
26 
27 private import gdk.GLContext;
28 private import glib.ConstructionException;
29 private import glib.ErrorG;
30 private import gobject.ObjectG;
31 private import gobject.Signals;
32 private import gtk.Widget;
33 private import gtk.c.functions;
34 public  import gtk.c.types;
35 private import std.algorithm;
36 
37 
38 /**
39  * `GtkGLArea` is a widget that allows drawing with OpenGL.
40  * 
41  * ![An example GtkGLArea](glarea.png)
42  * 
43  * `GtkGLArea` sets up its own [class@Gdk.GLContext], and creates a custom
44  * GL framebuffer that the widget will do GL rendering onto. It also ensures
45  * that this framebuffer is the default GL rendering target when rendering.
46  * 
47  * In order to draw, you have to connect to the [signal@Gtk.GLArea::render]
48  * signal, or subclass `GtkGLArea` and override the GtkGLAreaClass.render
49  * virtual function.
50  * 
51  * The `GtkGLArea` widget ensures that the `GdkGLContext` is associated with
52  * the widget's drawing area, and it is kept updated when the size and
53  * position of the drawing area changes.
54  * 
55  * ## Drawing with GtkGLArea
56  * 
57  * The simplest way to draw using OpenGL commands in a `GtkGLArea` is to
58  * create a widget instance and connect to the [signal@Gtk.GLArea::render] signal:
59  * 
60  * The `render()` function will be called when the `GtkGLArea` is ready
61  * for you to draw its content:
62  * 
63  * ```c
64  * static gboolean
65  * render (GtkGLArea *area, GdkGLContext *context)
66  * {
67  * // inside this function it's safe to use GL; the given
68  * // #GdkGLContext has been made current to the drawable
69  * // surface used by the `GtkGLArea` and the viewport has
70  * // already been set to be the size of the allocation
71  * 
72  * // we can start by clearing the buffer
73  * glClearColor (0, 0, 0, 0);
74  * glClear (GL_COLOR_BUFFER_BIT);
75  * 
76  * // draw your object
77  * // draw_an_object ();
78  * 
79  * // we completed our drawing; the draw commands will be
80  * // flushed at the end of the signal emission chain, and
81  * // the buffers will be drawn on the window
82  * return TRUE;
83  * }
84  * 
85  * void setup_glarea (void)
86  * {
87  * // create a GtkGLArea instance
88  * GtkWidget *gl_area = gtk_gl_area_new ();
89  * 
90  * // connect to the "render" signal
91  * g_signal_connect (gl_area, "render", G_CALLBACK (render), NULL);
92  * }
93  * ```
94  * 
95  * If you need to initialize OpenGL state, e.g. buffer objects or
96  * shaders, you should use the [signal@Gtk.Widget::realize] signal;
97  * you can use the [signal@Gtk.Widget::unrealize] signal to clean up.
98  * Since the `GdkGLContext` creation and initialization may fail, you
99  * will need to check for errors, using [method@Gtk.GLArea.get_error].
100  * 
101  * An example of how to safely initialize the GL state is:
102  * 
103  * ```c
104  * static void
105  * on_realize (GtkGLarea *area)
106  * {
107  * // We need to make the context current if we want to
108  * // call GL API
109  * gtk_gl_area_make_current (area);
110  * 
111  * // If there were errors during the initialization or
112  * // when trying to make the context current, this
113  * // function will return a #GError for you to catch
114  * if (gtk_gl_area_get_error (area) != NULL)
115  * return;
116  * 
117  * // You can also use gtk_gl_area_set_error() in order
118  * // to show eventual initialization errors on the
119  * // GtkGLArea widget itself
120  * GError *internal_error = NULL;
121  * init_buffer_objects (&error);
122  * if (error != NULL)
123  * {
124  * gtk_gl_area_set_error (area, error);
125  * g_error_free (error);
126  * return;
127  * }
128  * 
129  * init_shaders (&error);
130  * if (error != NULL)
131  * {
132  * gtk_gl_area_set_error (area, error);
133  * g_error_free (error);
134  * return;
135  * }
136  * }
137  * ```
138  * 
139  * If you need to change the options for creating the `GdkGLContext`
140  * you should use the [signal@Gtk.GLArea::create-context] signal.
141  */
142 public class GLArea : Widget
143 {
144 	/** the main Gtk struct */
145 	protected GtkGLArea* gtkGLArea;
146 
147 	/** Get the main Gtk struct */
148 	public GtkGLArea* getGLAreaStruct(bool transferOwnership = false)
149 	{
150 		if (transferOwnership)
151 			ownedRef = false;
152 		return gtkGLArea;
153 	}
154 
155 	/** the main Gtk struct as a void* */
156 	protected override void* getStruct()
157 	{
158 		return cast(void*)gtkGLArea;
159 	}
160 
161 	/**
162 	 * Sets our main struct and passes it to the parent class.
163 	 */
164 	public this (GtkGLArea* gtkGLArea, bool ownedRef = false)
165 	{
166 		this.gtkGLArea = gtkGLArea;
167 		super(cast(GtkWidget*)gtkGLArea, ownedRef);
168 	}
169 
170 
171 	/** */
172 	public static GType getType()
173 	{
174 		return gtk_gl_area_get_type();
175 	}
176 
177 	/**
178 	 * Creates a new `GtkGLArea` widget.
179 	 *
180 	 * Returns: a new `GtkGLArea`
181 	 *
182 	 * Throws: ConstructionException GTK+ fails to create the object.
183 	 */
184 	public this()
185 	{
186 		auto __p = gtk_gl_area_new();
187 
188 		if(__p is null)
189 		{
190 			throw new ConstructionException("null returned by new");
191 		}
192 
193 		this(cast(GtkGLArea*) __p);
194 	}
195 
196 	/**
197 	 * Binds buffers to the framebuffer.
198 	 *
199 	 * Ensures that the @area framebuffer object is made the current draw
200 	 * and read target, and that all the required buffers for the @area
201 	 * are created and bound to the framebuffer.
202 	 *
203 	 * This function is automatically called before emitting the
204 	 * [signal@Gtk.GLArea::render] signal, and doesn't normally need to be
205 	 * called by application code.
206 	 */
207 	public void attachBuffers()
208 	{
209 		gtk_gl_area_attach_buffers(gtkGLArea);
210 	}
211 
212 	/**
213 	 * Returns whether the area is in auto render mode or not.
214 	 *
215 	 * Returns: %TRUE if the @area is auto rendering, %FALSE otherwise
216 	 */
217 	public bool getAutoRender()
218 	{
219 		return gtk_gl_area_get_auto_render(gtkGLArea) != 0;
220 	}
221 
222 	/**
223 	 * Retrieves the `GdkGLContext` used by @area.
224 	 *
225 	 * Returns: the `GdkGLContext`
226 	 */
227 	public GLContext getContext()
228 	{
229 		auto __p = gtk_gl_area_get_context(gtkGLArea);
230 
231 		if(__p is null)
232 		{
233 			return null;
234 		}
235 
236 		return ObjectG.getDObject!(GLContext)(cast(GdkGLContext*) __p);
237 	}
238 
239 	/**
240 	 * Gets the current error set on the @area.
241 	 *
242 	 * Returns: the #GError or %NULL
243 	 */
244 	public ErrorG getError()
245 	{
246 		auto __p = gtk_gl_area_get_error(gtkGLArea);
247 
248 		if(__p is null)
249 		{
250 			return null;
251 		}
252 
253 		return new ErrorG(cast(GError*) __p);
254 	}
255 
256 	/**
257 	 * Returns whether the area has a depth buffer.
258 	 *
259 	 * Returns: %TRUE if the @area has a depth buffer, %FALSE otherwise
260 	 */
261 	public bool getHasDepthBuffer()
262 	{
263 		return gtk_gl_area_get_has_depth_buffer(gtkGLArea) != 0;
264 	}
265 
266 	/**
267 	 * Returns whether the area has a stencil buffer.
268 	 *
269 	 * Returns: %TRUE if the @area has a stencil buffer, %FALSE otherwise
270 	 */
271 	public bool getHasStencilBuffer()
272 	{
273 		return gtk_gl_area_get_has_stencil_buffer(gtkGLArea) != 0;
274 	}
275 
276 	/**
277 	 * Retrieves the required version of OpenGL.
278 	 *
279 	 * See [method@Gtk.GLArea.set_required_version].
280 	 *
281 	 * Params:
282 	 *     major = return location for the required major version
283 	 *     minor = return location for the required minor version
284 	 */
285 	public void getRequiredVersion(out int major, out int minor)
286 	{
287 		gtk_gl_area_get_required_version(gtkGLArea, &major, &minor);
288 	}
289 
290 	/**
291 	 * Returns whether the `GtkGLArea` should use OpenGL ES.
292 	 *
293 	 * See [method@Gtk.GLArea.set_use_es].
294 	 *
295 	 * Returns: %TRUE if the `GtkGLArea` should create an OpenGL ES context
296 	 *     and %FALSE otherwise
297 	 */
298 	public bool getUseEs()
299 	{
300 		return gtk_gl_area_get_use_es(gtkGLArea) != 0;
301 	}
302 
303 	/**
304 	 * Ensures that the `GdkGLContext` used by @area is associated with
305 	 * the `GtkGLArea`.
306 	 *
307 	 * This function is automatically called before emitting the
308 	 * [signal@Gtk.GLArea::render] signal, and doesn't normally need
309 	 * to be called by application code.
310 	 */
311 	public void makeCurrent()
312 	{
313 		gtk_gl_area_make_current(gtkGLArea);
314 	}
315 
316 	/**
317 	 * Marks the currently rendered data (if any) as invalid, and queues
318 	 * a redraw of the widget.
319 	 *
320 	 * This ensures that the [signal@Gtk.GLArea::render] signal
321 	 * is emitted during the draw.
322 	 *
323 	 * This is only needed when [method@Gtk.GLArea.set_auto_render] has
324 	 * been called with a %FALSE value. The default behaviour is to
325 	 * emit [signal@Gtk.GLArea::render] on each draw.
326 	 */
327 	public void queueRender()
328 	{
329 		gtk_gl_area_queue_render(gtkGLArea);
330 	}
331 
332 	/**
333 	 * Sets whether the `GtkGLArea` is in auto render mode.
334 	 *
335 	 * If @auto_render is %TRUE the [signal@Gtk.GLArea::render] signal will
336 	 * be emitted every time the widget draws. This is the default and is
337 	 * useful if drawing the widget is faster.
338 	 *
339 	 * If @auto_render is %FALSE the data from previous rendering is kept
340 	 * around and will be used for drawing the widget the next time,
341 	 * unless the window is resized. In order to force a rendering
342 	 * [method@Gtk.GLArea.queue_render] must be called. This mode is
343 	 * useful when the scene changes seldom, but takes a long time to redraw.
344 	 *
345 	 * Params:
346 	 *     autoRender = a boolean
347 	 */
348 	public void setAutoRender(bool autoRender)
349 	{
350 		gtk_gl_area_set_auto_render(gtkGLArea, autoRender);
351 	}
352 
353 	/**
354 	 * Sets an error on the area which will be shown instead of the
355 	 * GL rendering.
356 	 *
357 	 * This is useful in the [signal@Gtk.GLArea::create-context]
358 	 * signal if GL context creation fails.
359 	 *
360 	 * Params:
361 	 *     error = a new `GError`, or %NULL to unset the error
362 	 */
363 	public void setError(ErrorG error)
364 	{
365 		gtk_gl_area_set_error(gtkGLArea, (error is null) ? null : error.getErrorGStruct());
366 	}
367 
368 	/**
369 	 * Sets whether the `GtkGLArea` should use a depth buffer.
370 	 *
371 	 * If @has_depth_buffer is %TRUE the widget will allocate and
372 	 * enable a depth buffer for the target framebuffer. Otherwise
373 	 * there will be none.
374 	 *
375 	 * Params:
376 	 *     hasDepthBuffer = %TRUE to add a depth buffer
377 	 */
378 	public void setHasDepthBuffer(bool hasDepthBuffer)
379 	{
380 		gtk_gl_area_set_has_depth_buffer(gtkGLArea, hasDepthBuffer);
381 	}
382 
383 	/**
384 	 * Sets whether the `GtkGLArea` should use a stencil buffer.
385 	 *
386 	 * If @has_stencil_buffer is %TRUE the widget will allocate and
387 	 * enable a stencil buffer for the target framebuffer. Otherwise
388 	 * there will be none.
389 	 *
390 	 * Params:
391 	 *     hasStencilBuffer = %TRUE to add a stencil buffer
392 	 */
393 	public void setHasStencilBuffer(bool hasStencilBuffer)
394 	{
395 		gtk_gl_area_set_has_stencil_buffer(gtkGLArea, hasStencilBuffer);
396 	}
397 
398 	/**
399 	 * Sets the required version of OpenGL to be used when creating
400 	 * the context for the widget.
401 	 *
402 	 * This function must be called before the area has been realized.
403 	 *
404 	 * Params:
405 	 *     major = the major version
406 	 *     minor = the minor version
407 	 */
408 	public void setRequiredVersion(int major, int minor)
409 	{
410 		gtk_gl_area_set_required_version(gtkGLArea, major, minor);
411 	}
412 
413 	/**
414 	 * Sets whether the @area should create an OpenGL or an OpenGL ES context.
415 	 *
416 	 * You should check the capabilities of the #GdkGLContext before drawing
417 	 * with either API.
418 	 *
419 	 * Params:
420 	 *     useEs = whether to use OpenGL or OpenGL ES
421 	 */
422 	public void setUseEs(bool useEs)
423 	{
424 		gtk_gl_area_set_use_es(gtkGLArea, useEs);
425 	}
426 
427 	/**
428 	 * Emitted when the widget is being realized.
429 	 *
430 	 * This allows you to override how the GL context is created.
431 	 * This is useful when you want to reuse an existing GL context,
432 	 * or if you want to try creating different kinds of GL options.
433 	 *
434 	 * If context creation fails then the signal handler can use
435 	 * [method@Gtk.GLArea.set_error] to register a more detailed error
436 	 * of how the construction failed.
437 	 *
438 	 * Returns: a newly created `GdkGLContext`;
439 	 *     the `GtkGLArea` widget will take ownership of the returned value.
440 	 */
441 	gulong addOnCreateContext(GLContext delegate(GLArea) dlg, ConnectFlags connectFlags=cast(ConnectFlags)0)
442 	{
443 		return Signals.connect(this, "create-context", dlg, connectFlags ^ ConnectFlags.SWAPPED);
444 	}
445 
446 	/**
447 	 * Emitted every time the contents of the `GtkGLArea` should be redrawn.
448 	 *
449 	 * The @context is bound to the @area prior to emitting this function,
450 	 * and the buffers are painted to the window once the emission terminates.
451 	 *
452 	 * Params:
453 	 *     context = the `GdkGLContext` used by @area
454 	 *
455 	 * Returns: %TRUE to stop other handlers from being invoked for the event.
456 	 *     %FALSE to propagate the event further.
457 	 */
458 	gulong addOnRender(bool delegate(GLContext, GLArea) dlg, ConnectFlags connectFlags=cast(ConnectFlags)0)
459 	{
460 		return Signals.connect(this, "render", dlg, connectFlags ^ ConnectFlags.SWAPPED);
461 	}
462 
463 	/**
464 	 * Emitted once when the widget is realized, and then each time the widget
465 	 * is changed while realized.
466 	 *
467 	 * This is useful in order to keep GL state up to date with the widget size,
468 	 * like for instance camera properties which may depend on the width/height
469 	 * ratio.
470 	 *
471 	 * The GL context for the area is guaranteed to be current when this signal
472 	 * is emitted.
473 	 *
474 	 * The default handler sets up the GL viewport.
475 	 *
476 	 * Params:
477 	 *     width = the width of the viewport
478 	 *     height = the height of the viewport
479 	 */
480 	gulong addOnResize(void delegate(int, int, GLArea) dlg, ConnectFlags connectFlags=cast(ConnectFlags)0)
481 	{
482 		return Signals.connect(this, "resize", dlg, connectFlags ^ ConnectFlags.SWAPPED);
483 	}
484 }