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 }