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 public import gtkc.gtktypes; 36 private import std.algorithm; 37 38 39 /** 40 * #GtkGLArea is a widget that allows drawing with OpenGL. 41 * 42 * #GtkGLArea sets up its own #GdkGLContext for the window it creates, and 43 * creates a custom GL framebuffer that the widget will do GL rendering onto. 44 * It also ensures that this framebuffer is the default GL rendering target 45 * when rendering. 46 * 47 * In order to draw, you have to connect to the #GtkGLArea::render signal, 48 * or subclass #GtkGLArea and override the @GtkGLAreaClass.render() virtual 49 * 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 #GtkGLArea::render signal: 59 * 60 * |[<!-- language="C" --> 61 * // create a GtkGLArea instance 62 * GtkWidget *gl_area = gtk_gl_area_new (); 63 * 64 * // connect to the "render" signal 65 * g_signal_connect (gl_area, "render", G_CALLBACK (render), NULL); 66 * ]| 67 * 68 * The `render()` function will be called when the #GtkGLArea is ready 69 * for you to draw its content: 70 * 71 * |[<!-- language="C" --> 72 * static gboolean 73 * render (GtkGLArea *area, GdkGLContext *context) 74 * { 75 * // inside this function it's safe to use GL; the given 76 * // #GdkGLContext has been made current to the drawable 77 * // surface used by the #GtkGLArea and the viewport has 78 * // already been set to be the size of the allocation 79 * 80 * // we can start by clearing the buffer 81 * glClearColor (0, 0, 0, 0); 82 * glClear (GL_COLOR_BUFFER_BIT); 83 * 84 * // draw your object 85 * draw_an_object (); 86 * 87 * // we completed our drawing; the draw commands will be 88 * // flushed at the end of the signal emission chain, and 89 * // the buffers will be drawn on the window 90 * return TRUE; 91 * } 92 * ]| 93 * 94 * If you need to initialize OpenGL state, e.g. buffer objects or 95 * shaders, you should use the #GtkWidget::realize signal; you 96 * can use the #GtkWidget::unrealize signal to clean up. Since the 97 * #GdkGLContext creation and initialization may fail, you will 98 * need to check for errors, using gtk_gl_area_get_error(). An example 99 * of how to safely initialize the GL state is: 100 * 101 * |[<!-- language="C" --> 102 * static void 103 * on_realize (GtkGLarea *area) 104 * { 105 * // We need to make the context current if we want to 106 * // call GL API 107 * gtk_gl_area_make_current (area); 108 * 109 * // If there were errors during the initialization or 110 * // when trying to make the context current, this 111 * // function will return a #GError for you to catch 112 * if (gtk_gl_area_get_error (area) != NULL) 113 * return; 114 * 115 * // You can also use gtk_gl_area_set_error() in order 116 * // to show eventual initialization errors on the 117 * // GtkGLArea widget itself 118 * GError *internal_error = NULL; 119 * init_buffer_objects (&error); 120 * if (error != NULL) 121 * { 122 * gtk_gl_area_set_error (area, error); 123 * g_error_free (error); 124 * return; 125 * } 126 * 127 * init_shaders (&error); 128 * if (error != NULL) 129 * { 130 * gtk_gl_area_set_error (area, error); 131 * g_error_free (error); 132 * return; 133 * } 134 * } 135 * ]| 136 * 137 * If you need to change the options for creating the #GdkGLContext 138 * you should use the #GtkGLArea::create-context signal. 139 * 140 * Since: 3.16 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 * Since: 3.16 183 * 184 * Throws: ConstructionException GTK+ fails to create the object. 185 */ 186 public this() 187 { 188 auto p = gtk_gl_area_new(); 189 190 if(p is null) 191 { 192 throw new ConstructionException("null returned by new"); 193 } 194 195 this(cast(GtkGLArea*) p); 196 } 197 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 frambuffer. 202 * 203 * This function is automatically called before emitting the 204 * #GtkGLArea::render signal, and doesn't normally need to be called 205 * by application code. 206 * 207 * Since: 3.16 208 */ 209 public void attachBuffers() 210 { 211 gtk_gl_area_attach_buffers(gtkGLArea); 212 } 213 214 /** 215 * Returns whether the area is in auto render mode or not. 216 * 217 * Returns: %TRUE if the @area is auto rendering, %FALSE otherwise 218 * 219 * Since: 3.16 220 */ 221 public bool getAutoRender() 222 { 223 return gtk_gl_area_get_auto_render(gtkGLArea) != 0; 224 } 225 226 /** 227 * Retrieves the #GdkGLContext used by @area. 228 * 229 * Returns: the #GdkGLContext 230 * 231 * Since: 3.16 232 */ 233 public GLContext getContext() 234 { 235 auto p = gtk_gl_area_get_context(gtkGLArea); 236 237 if(p is null) 238 { 239 return null; 240 } 241 242 return ObjectG.getDObject!(GLContext)(cast(GdkGLContext*) p); 243 } 244 245 /** 246 * Gets the current error set on the @area. 247 * 248 * Returns: the #GError or %NULL 249 * 250 * Since: 3.16 251 */ 252 public ErrorG getError() 253 { 254 auto p = gtk_gl_area_get_error(gtkGLArea); 255 256 if(p is null) 257 { 258 return null; 259 } 260 261 return new ErrorG(cast(GError*) p); 262 } 263 264 /** 265 * Returns whether the area has an alpha component. 266 * 267 * Returns: %TRUE if the @area has an alpha component, %FALSE otherwise 268 * 269 * Since: 3.16 270 */ 271 public bool getHasAlpha() 272 { 273 return gtk_gl_area_get_has_alpha(gtkGLArea) != 0; 274 } 275 276 /** 277 * Returns whether the area has a depth buffer. 278 * 279 * Returns: %TRUE if the @area has a depth buffer, %FALSE otherwise 280 * 281 * Since: 3.16 282 */ 283 public bool getHasDepthBuffer() 284 { 285 return gtk_gl_area_get_has_depth_buffer(gtkGLArea) != 0; 286 } 287 288 /** 289 * Returns whether the area has a stencil buffer. 290 * 291 * Returns: %TRUE if the @area has a stencil buffer, %FALSE otherwise 292 * 293 * Since: 3.16 294 */ 295 public bool getHasStencilBuffer() 296 { 297 return gtk_gl_area_get_has_stencil_buffer(gtkGLArea) != 0; 298 } 299 300 /** 301 * Retrieves the required version of OpenGL set 302 * using gtk_gl_area_set_required_version(). 303 * 304 * Params: 305 * major = return location for the required major version 306 * minor = return location for the required minor version 307 * 308 * Since: 3.16 309 */ 310 public void getRequiredVersion(out int major, out int minor) 311 { 312 gtk_gl_area_get_required_version(gtkGLArea, &major, &minor); 313 } 314 315 /** 316 * Retrieves the value set by gtk_gl_area_set_use_es(). 317 * 318 * Returns: %TRUE if the #GtkGLArea should create an OpenGL ES context 319 * and %FALSE otherwise 320 * 321 * Since: 3.22 322 */ 323 public bool getUseEs() 324 { 325 return gtk_gl_area_get_use_es(gtkGLArea) != 0; 326 } 327 328 /** 329 * Ensures that the #GdkGLContext used by @area is associated with 330 * the #GtkGLArea. 331 * 332 * This function is automatically called before emitting the 333 * #GtkGLArea::render signal, and doesn't normally need to be called 334 * by application code. 335 * 336 * Since: 3.16 337 */ 338 public void makeCurrent() 339 { 340 gtk_gl_area_make_current(gtkGLArea); 341 } 342 343 /** 344 * Marks the currently rendered data (if any) as invalid, and queues 345 * a redraw of the widget, ensuring that the #GtkGLArea::render signal 346 * is emitted during the draw. 347 * 348 * This is only needed when the gtk_gl_area_set_auto_render() has 349 * been called with a %FALSE value. The default behaviour is to 350 * emit #GtkGLArea::render on each draw. 351 * 352 * Since: 3.16 353 */ 354 public void queueRender() 355 { 356 gtk_gl_area_queue_render(gtkGLArea); 357 } 358 359 /** 360 * If @auto_render is %TRUE the #GtkGLArea::render signal will be 361 * emitted every time the widget draws. This is the default and is 362 * useful if drawing the widget is faster. 363 * 364 * If @auto_render is %FALSE the data from previous rendering is kept 365 * around and will be used for drawing the widget the next time, 366 * unless the window is resized. In order to force a rendering 367 * gtk_gl_area_queue_render() must be called. This mode is useful when 368 * the scene changes seldomly, but takes a long time to redraw. 369 * 370 * Params: 371 * autoRender = a boolean 372 * 373 * Since: 3.16 374 */ 375 public void setAutoRender(bool autoRender) 376 { 377 gtk_gl_area_set_auto_render(gtkGLArea, autoRender); 378 } 379 380 /** 381 * Sets an error on the area which will be shown instead of the 382 * GL rendering. This is useful in the #GtkGLArea::create-context 383 * signal if GL context creation fails. 384 * 385 * Params: 386 * error = a new #GError, or %NULL to unset the error 387 * 388 * Since: 3.16 389 */ 390 public void setError(ErrorG error) 391 { 392 gtk_gl_area_set_error(gtkGLArea, (error is null) ? null : error.getErrorGStruct()); 393 } 394 395 /** 396 * If @has_alpha is %TRUE the buffer allocated by the widget will have 397 * an alpha channel component, and when rendering to the window the 398 * result will be composited over whatever is below the widget. 399 * 400 * If @has_alpha is %FALSE there will be no alpha channel, and the 401 * buffer will fully replace anything below the widget. 402 * 403 * Params: 404 * hasAlpha = %TRUE to add an alpha component 405 * 406 * Since: 3.16 407 */ 408 public void setHasAlpha(bool hasAlpha) 409 { 410 gtk_gl_area_set_has_alpha(gtkGLArea, hasAlpha); 411 } 412 413 /** 414 * If @has_depth_buffer is %TRUE the widget will allocate and 415 * enable a depth buffer for the target framebuffer. Otherwise 416 * there will be none. 417 * 418 * Params: 419 * hasDepthBuffer = %TRUE to add a depth buffer 420 * 421 * Since: 3.16 422 */ 423 public void setHasDepthBuffer(bool hasDepthBuffer) 424 { 425 gtk_gl_area_set_has_depth_buffer(gtkGLArea, hasDepthBuffer); 426 } 427 428 /** 429 * If @has_stencil_buffer is %TRUE the widget will allocate and 430 * enable a stencil buffer for the target framebuffer. Otherwise 431 * there will be none. 432 * 433 * Params: 434 * hasStencilBuffer = %TRUE to add a stencil buffer 435 * 436 * Since: 3.16 437 */ 438 public void setHasStencilBuffer(bool hasStencilBuffer) 439 { 440 gtk_gl_area_set_has_stencil_buffer(gtkGLArea, hasStencilBuffer); 441 } 442 443 /** 444 * Sets the required version of OpenGL to be used when creating the context 445 * for the widget. 446 * 447 * This function must be called before the area has been realized. 448 * 449 * Params: 450 * major = the major version 451 * minor = the minor version 452 * 453 * Since: 3.16 454 */ 455 public void setRequiredVersion(int major, int minor) 456 { 457 gtk_gl_area_set_required_version(gtkGLArea, major, minor); 458 } 459 460 /** 461 * Sets whether the @area should create an OpenGL or an OpenGL ES context. 462 * 463 * You should check the capabilities of the #GdkGLContext before drawing 464 * with either API. 465 * 466 * Params: 467 * useEs = whether to use OpenGL or OpenGL ES 468 * 469 * Since: 3.22 470 */ 471 public void setUseEs(bool useEs) 472 { 473 gtk_gl_area_set_use_es(gtkGLArea, useEs); 474 } 475 476 /** 477 * The ::create-context signal is emitted when the widget is being 478 * realized, and allows you to override how the GL context is 479 * created. This is useful when you want to reuse an existing GL 480 * context, or if you want to try creating different kinds of GL 481 * options. 482 * 483 * If context creation fails then the signal handler can use 484 * gtk_gl_area_set_error() to register a more detailed error 485 * of how the construction failed. 486 * 487 * Returns: a newly created #GdkGLContext; 488 * the #GtkGLArea widget will take ownership of the returned value. 489 * 490 * Since: 3.16 491 */ 492 gulong addOnCreateContext(GLContext delegate(GLArea) dlg, ConnectFlags connectFlags=cast(ConnectFlags)0) 493 { 494 return Signals.connect(this, "create-context", dlg, connectFlags ^ ConnectFlags.SWAPPED); 495 } 496 497 /** 498 * The ::render signal is emitted every time the contents 499 * of the #GtkGLArea should be redrawn. 500 * 501 * The @context is bound to the @area prior to emitting this function, 502 * and the buffers are painted to the window once the emission terminates. 503 * 504 * Params: 505 * context = the #GdkGLContext used by @area 506 * 507 * Returns: %TRUE to stop other handlers from being invoked for the event. 508 * %FALSE to propagate the event further. 509 * 510 * Since: 3.16 511 */ 512 gulong addOnRender(bool delegate(GLContext, GLArea) dlg, ConnectFlags connectFlags=cast(ConnectFlags)0) 513 { 514 return Signals.connect(this, "render", dlg, connectFlags ^ ConnectFlags.SWAPPED); 515 } 516 517 /** 518 * The ::resize signal is emitted once when the widget is realized, and 519 * then each time the widget is changed while realized. This is useful 520 * in order to keep GL state up to date with the widget size, like for 521 * instance camera properties which may depend on the width/height ratio. 522 * 523 * The GL context for the area is guaranteed to be current when this signal 524 * is emitted. 525 * 526 * The default handler sets up the GL viewport. 527 * 528 * Params: 529 * width = the width of the viewport 530 * height = the height of the viewport 531 * 532 * Since: 3.16 533 */ 534 gulong addOnResize(void delegate(int, int, GLArea) dlg, ConnectFlags connectFlags=cast(ConnectFlags)0) 535 { 536 return Signals.connect(this, "resize", dlg, connectFlags ^ ConnectFlags.SWAPPED); 537 } 538 }