1 /* 2 * DSFML - The Simple and Fast Multimedia Library for D 3 * 4 * Copyright (c) 2013 - 2018 Jeremy DeHaan (dehaan.jeremiah@gmail.com) 5 * 6 * This software is provided 'as-is', without any express or implied warranty. 7 * In no event will the authors be held liable for any damages arising from the 8 * use of this software. 9 * 10 * Permission is granted to anyone to use this software for any purpose, 11 * including commercial applications, and to alter it and redistribute it 12 * freely, subject to the following restrictions: 13 * 14 * 1. The origin of this software must not be misrepresented; you must not claim 15 * that you wrote the original software. If you use this software in a product, 16 * an acknowledgment in the product documentation would be appreciated but is 17 * not required. 18 * 19 * 2. Altered source versions must be plainly marked as such, and must not be 20 * misrepresented as being the original software. 21 * 22 * 3. This notice may not be removed or altered from any source distribution 23 * 24 * 25 * DSFML is based on SFML (Copyright Laurent Gomila) 26 */ 27 28 /** 29 * $(U RenderWindow) is the main class of the Graphics package. It defines an OS 30 * window that can be painted using the other classes of the graphics module. 31 * 32 * $(U RenderWindow) is derived from $(WINDOW_LINK), thus it inherits all its 33 * features : events, window management, OpenGL rendering, etc. See the 34 * documentation of $(WINDOW_LINK) for a more complete description of all these 35 * features, as well as code examples. 36 * 37 * On top of that, $(U RenderWindow) adds more features related to 2D drawing 38 * with the graphics module (see its base class $(RENDERTARGET_LINK) for more 39 * details). 40 * 41 * Here is a typical rendering and event loop with a $(U RenderWindow): 42 * --- 43 * // Declare and create a new render-window 44 * auto window = new RenderWindow(VideoMode(800, 600), "DSFML window"); 45 * 46 * // Limit the framerate to 60 frames per second (this step is optional) 47 * window.setFramerateLimit(60); 48 * 49 * // The main loop - ends as soon as the window is closed 50 * while (window.isOpen()) 51 * { 52 * // Event processing 53 * Event event; 54 * while (window.pollEvent(event)) 55 * { 56 * // Request for closing the window 57 * if (event.type == Event.EventType.Closed) 58 * window.close(); 59 * } 60 * 61 * // Clear the whole window before rendering a new frame 62 * window.clear(); 63 * 64 * // Draw some graphical entities 65 * window.draw(sprite); 66 * window.draw(circle); 67 * window.draw(text); 68 * 69 * // End the current frame and display its contents on screen 70 * window.display(); 71 * } 72 * --- 73 * 74 * $(PARA Like $(WINDOW_LINK), $(U RenderWindow) is still able to render direct 75 * OpenGL stuff. It is even possible to mix together OpenGL calls and regular 76 * DSFML drawing commands.) 77 * --- 78 * // Create the render window 79 * auto window = new RenderWindow(VideoMode(800, 600), "DSFML OpenGL"); 80 * 81 * // Create a sprite and a text to display 82 * auto sprite = new Sprite(); 83 * auto text = new Text(); 84 * ... 85 * 86 * // Perform OpenGL initializations 87 * glMatrixMode(GL_PROJECTION); 88 * ... 89 * 90 * // Start the rendering loop 91 * while (window.isOpen()) 92 * { 93 * // Process events 94 * ... 95 * 96 * // Draw a background sprite 97 * window.pushGLStates(); 98 * window.draw(sprite); 99 * window.popGLStates(); 100 * 101 * // Draw a 3D object using OpenGL 102 * glBegin(GL_QUADS); 103 * glVertex3f(...); 104 * ... 105 * glEnd(); 106 * 107 * // Draw text on top of the 3D object 108 * window.pushGLStates(); 109 * window.draw(text); 110 * window.popGLStates(); 111 * 112 * // Finally, display the rendered frame on screen 113 * window.display(); 114 * } 115 * --- 116 * 117 * See_Also: 118 * $(WINDOW_LINK), $(RENDERTARGET_LINK), $(RENDERTEXTURE_LINK), $(VIEW_LINK) 119 */ 120 module dsfml.graphics.renderwindow; 121 122 import dsfml.graphics.color; 123 import dsfml.graphics.image; 124 import dsfml.graphics.rect; 125 import dsfml.graphics.drawable; 126 import dsfml.graphics.primitivetype; 127 import dsfml.graphics.renderstates; 128 import dsfml.graphics.rendertarget; 129 import dsfml.graphics.shader; 130 import dsfml.graphics.text; 131 import dsfml.graphics.texture; 132 import dsfml.graphics.view; 133 import dsfml.graphics.vertex; 134 135 import dsfml.window.contextsettings; 136 import dsfml.window.windowhandle; 137 import dsfml.window.event; 138 import dsfml.window.window; 139 import dsfml.window.videomode; 140 141 import dsfml.system.err; 142 import dsfml.system.vector2; 143 144 /** 145 * Window that can serve as a target for 2D drawing. 146 */ 147 class RenderWindow : Window, RenderTarget 148 { 149 package sfRenderWindow* sfPtr; 150 private View m_currentView, m_defaultView; 151 152 /** 153 * Default constructor. 154 * 155 * This constructor doesn't actually create the window, use the other 156 * constructors or call `create()` to do so. 157 */ 158 this() 159 { 160 sfPtr = sfRenderWindow_construct(); 161 super(0); 162 } 163 164 /** 165 * Construct a new window. 166 * 167 * This constructor creates the window with the size and pixel depth defined 168 * in mode. An optional style can be passed to customize the look and 169 * behavior of the window (borders, title bar, resizable, closable, ...). 170 * 171 * The fourth parameter is an optional structure specifying advanced OpenGL 172 * context settings such as antialiasing, depth-buffer bits, etc. You 173 * shouldn't care about these parameters for a regular usage of the graphics 174 * module. 175 * 176 * Params: 177 * mode = Video mode to use (defines the width, height and depth of the 178 * rendering area of the window) 179 * title = Title of the window 180 * style = Window style, a bitwise OR combination of Style enumerators 181 * settings = Additional settings for the underlying OpenGL context 182 * 183 * Deprecated: Use the constructor that takes a 'const(dchar)[]' instead. 184 */ 185 deprecated("Use the constructor that takes a 'const(dchar)[]' instead.") 186 this(T)(VideoMode mode, const(T)[] title, Style style = Style.DefaultStyle, ContextSettings settings = ContextSettings.init) 187 if (is(T == wchar)||is(T == char)) 188 { 189 this(); 190 create(mode, title, style, settings); 191 } 192 193 /** 194 * Construct a new window. 195 * 196 * This constructor creates the window with the size and pixel depth defined 197 * in mode. An optional style can be passed to customize the look and 198 * behavior of the window (borders, title bar, resizable, closable, ...). 199 * 200 * The fourth parameter is an optional structure specifying advanced OpenGL 201 * context settings such as antialiasing, depth-buffer bits, etc. You 202 * shouldn't care about these parameters for a regular usage of the graphics 203 * module. 204 * 205 * Params: 206 * mode = Video mode to use (defines the width, height and depth of the 207 * rendering area of the window) 208 * title = Title of the window 209 * style = Window style, a bitwise OR combination of Style enumerators 210 * settings = Additional settings for the underlying OpenGL context 211 */ 212 this(T)(VideoMode mode, const(dchar)[] title, Style style = Style.DefaultStyle, ContextSettings settings = ContextSettings.init) 213 { 214 this(); 215 create(mode, title, style, settings); 216 } 217 218 /** 219 * Construct the window from an existing control. 220 * 221 * Use this constructor if you want to create an DSFML rendering area into 222 * an already existing control. 223 * 224 * The second parameter is an optional structure specifying advanced OpenGL 225 * context settings such as antialiasing, depth-buffer bits, etc. You 226 * shouldn't care about these parameters for a regular usage of the graphics 227 * module. 228 * 229 * Params: 230 * handle = Platform-specific handle of the control 231 * settings = Additional settings for the underlying OpenGL context 232 */ 233 this(WindowHandle handle, ContextSettings settings = ContextSettings.init) 234 { 235 this(); 236 create(handle, settings); 237 } 238 239 ~this() 240 { 241 import dsfml.system.config; 242 mixin(destructorOutput); 243 sfRenderWindow_destroy(sfPtr); 244 } 245 246 @property 247 { 248 /** 249 * Change the position of the window on screen. 250 * 251 * This property only works for top-level windows (i.e. it will be 252 * ignored for windows created from the handle of a child 253 * window/control). 254 */ 255 override Vector2i position(Vector2i newPosition) 256 { 257 sfRenderWindow_setPosition(sfPtr,newPosition.x, newPosition.y); 258 return newPosition; 259 } 260 261 /// ditto 262 override Vector2i position() const 263 { 264 Vector2i temp; 265 sfRenderWindow_getPosition(sfPtr,&temp.x, &temp.y); 266 return temp; 267 } 268 } 269 270 @property 271 { 272 /** 273 * The size of the rendering region of the window. 274 */ 275 override Vector2u size(Vector2u newSize) 276 { 277 sfRenderWindow_setSize(sfPtr, newSize.x, newSize.y); 278 return newSize; 279 } 280 281 /// ditto 282 override Vector2u size() const 283 { 284 Vector2u temp; 285 sfRenderWindow_getSize(sfPtr,&temp.x, &temp.y); 286 return temp; 287 } 288 } 289 290 @property 291 { 292 /** 293 * Change the current active view. 294 * 295 * The view is like a 2D camera, it controls which part of the 2D scene 296 * is visible, and how it is viewed in the render-target. The new view 297 * will affect everything that is drawn, until another view is set. 298 * 299 * The render target keeps its own copy of the view object, so it is not 300 * necessary to keep the original one alive after calling this function. 301 * To restore the original view of the target, you can pass the result 302 * of `getDefaultView()` to this function. 303 */ 304 override View view(View newView) 305 { 306 sfRenderWindow_setView(sfPtr, newView.center.x, newView.center.y, newView.size.x, newView.size.y, newView.rotation, 307 newView.viewport.left, newView.viewport.top, newView.viewport.width, newView.viewport.height); 308 return newView; 309 } 310 311 /// ditto 312 override View view() const 313 { 314 View currentView; 315 316 Vector2f currentCenter, currentSize; 317 float currentRotation; 318 FloatRect currentViewport; 319 320 sfRenderWindow_getView(sfPtr, ¤tCenter.x, ¤tCenter.y, ¤tSize.x, ¤tSize.y, ¤tRotation, 321 ¤tViewport.left, ¤tViewport.top, ¤tViewport.width, ¤tViewport.height); 322 323 currentView.center = currentCenter; 324 currentView.size = currentSize; 325 currentView.rotation = currentRotation; 326 currentView.viewport = currentViewport; 327 328 return currentView; 329 } 330 } 331 332 /** 333 * Get the default view of the render target. 334 * 335 * The default view has the initial size of the render target, and never 336 * changes after the target has been created. 337 * 338 * Returns: The default view of the render target. 339 */ 340 View getDefaultView() const 341 { 342 View currentView; 343 344 Vector2f currentCenter, currentSize; 345 float currentRotation; 346 FloatRect currentViewport; 347 348 sfRenderWindow_getDefaultView(sfPtr, ¤tCenter.x, ¤tCenter.y, ¤tSize.x, ¤tSize.y, ¤tRotation, 349 ¤tViewport.left, ¤tViewport.top, ¤tViewport.width, ¤tViewport.height); 350 351 currentView.center = currentCenter; 352 currentView.size = currentSize; 353 currentView.rotation = currentRotation; 354 currentView.viewport = currentViewport; 355 356 return currentView; 357 } 358 359 /** 360 * Get the settings of the OpenGL context of the window. 361 * 362 * Note that these settings may be different from what was passed to the 363 * constructor or the `create()` function, if one or more settings were not 364 * supported. In this case, DSFML chose the closest match. 365 * 366 * Returns: Structure containing the OpenGL context settings 367 */ 368 override ContextSettings getSettings() const 369 { 370 ContextSettings temp; 371 sfRenderWindow_getSettings(sfPtr,&temp.depthBits, &temp.stencilBits, &temp.antialiasingLevel, &temp.majorVersion, &temp.minorVersion); 372 return temp; 373 } 374 375 //this is a duplicate with the size property. Need to look into that 376 //(Inherited from RenderTarget) 377 /** 378 * Return the size of the rendering region of the target. 379 * 380 * Returns: Size in pixels 381 */ 382 Vector2u getSize() const 383 { 384 Vector2u temp; 385 386 sfRenderWindow_getSize(sfPtr, &temp.x, &temp.y); 387 388 return temp; 389 } 390 391 /** 392 * Get the OS-specific handle of the window. 393 * 394 * The type of the returned handle is WindowHandle, which is a typedef to 395 * the handle type defined by the OS. You shouldn't need to use this 396 * function, unless you have very specific stuff to implement that SFML 397 * doesn't support, or implement a temporary workaround until a bug is 398 * fixed. 399 * 400 * Returns: System handle of the window 401 */ 402 override WindowHandle getSystemHandle() const 403 { 404 return sfRenderWindow_getSystemHandle(sfPtr); 405 } 406 407 /** 408 * Get the viewport of a view, applied to this render target. 409 * 410 * A window is active only on the current thread, if you want to make it 411 * active on another thread you have to deactivate it on the previous thread 412 * first if it was active. Only one window can be active on a thread at a 413 * time, thus the window previously active (if any) automatically gets 414 * deactivated. 415 * 416 * Params: 417 * active = true to activate, false to deactivate 418 * 419 * Returns: true if operation was successful, false otherwise 420 */ 421 override bool setActive(bool active) 422 { 423 return sfRenderWindow_setActive(sfPtr, active); 424 } 425 426 /** 427 * Limit the framerate to a maximum fixed frequency. 428 * 429 * If a limit is set, the window will use a small delay after each call to 430 * `display()` to ensure that the current frame lasted long enough to match 431 * the framerate limit. 432 * 433 * DSFML will try to match the given limit as much as it can, but since it 434 * internally uses sleep, whose precision depends on the underlying OS, the 435 * results may be a little unprecise as well (for example, you can get 65 436 * FPS when requesting 60). 437 * 438 * Params: 439 * limit = Framerate limit, in frames per seconds (use 0 to disable limit) 440 */ 441 override void setFramerateLimit(uint limit) 442 { 443 sfRenderWindow_setFramerateLimit(sfPtr, limit); 444 } 445 446 /** 447 * Change the window's icon. 448 * 449 * pixels must be an array of width x height pixels in 32-bits RGBA format. 450 * 451 * The OS default icon is used by default. 452 * 453 * Params: 454 * width = Icon's width, in pixels 455 * height = Icon's height, in pixels 456 * pixels = Icon pixel array to load from 457 */ 458 override void setIcon(uint width, uint height, const(ubyte[]) pixels) 459 { 460 sfRenderWindow_setIcon(sfPtr,width, height, pixels.ptr); 461 } 462 463 /** 464 * Change the joystick threshold. 465 * 466 * The joystick threshold is the value below which no JoystickMoved event 467 * will be generated. 468 * 469 * The threshold value is 0.1 by default. 470 * 471 * Params: 472 * threshold = New threshold, in the range [0, 100] 473 */ 474 override void setJoystickThreshold(float threshold) 475 { 476 sfRenderWindow_setJoystickThreshold(sfPtr, threshold); 477 } 478 479 /** 480 * Change the joystick threshold. 481 * 482 * The joystick threshold is the value below which no JoystickMoved event 483 * will be generated. 484 * 485 * The threshold value is 0.1 by default. 486 * 487 * Params: 488 * threshhold = New threshold, in the range [0, 100] 489 * 490 * Deprecated: Use set `setJoystickThreshold` instead. 491 */ 492 deprecated("Use setJoystickThreshold instead.") 493 override void setJoystickThreshhold(float threshhold) 494 { 495 sfRenderWindow_setJoystickThreshold(sfPtr, threshhold); 496 } 497 498 /** 499 * Enable or disable automatic key-repeat. 500 * 501 * If key repeat is enabled, you will receive repeated KeyPressed events 502 * while keeping a key pressed. If it is disabled, you will only get a 503 * single event when the key is pressed. 504 * 505 * Key repeat is enabled by default. 506 * 507 * Params: 508 * enabled = true to enable, false to disable 509 */ 510 override void setKeyRepeatEnabled(bool enabled) 511 { 512 sfRenderWindow_setKeyRepeatEnabled(sfPtr,enabled); 513 } 514 515 /** 516 * Show or hide the mouse cursor. 517 * 518 * The mouse cursor is visible by default. 519 * 520 * Params: 521 * visible = true show the mouse cursor, false to hide it 522 */ 523 override void setMouseCursorVisible(bool visible) 524 { 525 sfRenderWindow_setMouseCursorVisible(sfPtr, visible); 526 } 527 528 //Cannot use templates here as template member functions cannot be virtual. 529 530 /** 531 * Change the title of the window 532 * 533 * Params: 534 * newTitle = New title 535 */ 536 override void setTitle(const(char)[] newTitle) 537 { 538 import std.utf: toUTF32; 539 auto convertedTitle = toUTF32(newTitle); 540 sfRenderWindow_setUnicodeTitle(sfPtr, convertedTitle.ptr, convertedTitle.length); 541 } 542 /** 543 * Change the title of the window 544 * 545 * Params: 546 * newTitle = New title 547 */ 548 override void setTitle(const(wchar)[] newTitle) 549 { 550 import std.utf: toUTF32; 551 auto convertedTitle = toUTF32(newTitle); 552 sfRenderWindow_setUnicodeTitle(sfPtr, convertedTitle.ptr, convertedTitle.length); 553 } 554 /** 555 * Change the title of the window 556 * 557 * Params: 558 * newTitle = New title 559 */ 560 override void setTitle(const(dchar)[] newTitle) 561 { 562 import dsfml.system..string; 563 sfRenderWindow_setUnicodeTitle(sfPtr, newTitle.ptr, newTitle.length); 564 } 565 566 /** 567 * Enable or disable vertical synchronization. 568 * 569 * Activating vertical synchronization will limit the number of frames 570 * displayed to the refresh rate of the monitor. This can avoid some visual 571 * artifacts, and limit the framerate to a good value (but not constant 572 * across different computers). 573 * 574 * Vertical synchronization is disabled by default. 575 * 576 * Params: 577 * enabled = true to enable v-sync, false to deactivate it 578 */ 579 override void setVerticalSyncEnabled(bool enabled) 580 { 581 sfRenderWindow_setVerticalSyncEnabled(sfPtr, enabled); 582 } 583 584 /** 585 * Show or hide the window. 586 * 587 * The window is shown by default. 588 * 589 * Params: 590 * visible = true to show the window, false to hide it 591 */ 592 override void setVisible(bool visible) 593 { 594 sfRenderWindow_setVisible(sfPtr,visible); 595 } 596 597 /** 598 * Clear the entire target with a single color. 599 * 600 * This function is usually called once every frame, to clear the previous 601 * contents of the target. 602 * 603 * Params: 604 * color = Fill color to use to clear the render target 605 */ 606 void clear(Color color = Color.Black) 607 { 608 sfRenderWindow_clear(sfPtr, color.r,color.g, color.b, color.a); 609 } 610 611 /** 612 * Close the window and destroy all the attached resources. 613 * 614 * After calling this function, the Window instance remains valid and you 615 * can call `create()` to recreate the window. All other functions such as 616 * `pollEvent()` or `display()` will still work (i.e. you don't have to test 617 * `isOpen()` every time), and will have no effect on closed windows. 618 */ 619 override void close() 620 { 621 sfRenderWindow_close(sfPtr); 622 } 623 624 //Cannot use templates here as template member functions cannot be virtual. 625 626 /** 627 * Create (or recreate) the window. 628 * 629 * If the window was already created, it closes it first. If style contains 630 * Window.Style.Fullscreen, then mode must be a valid video mode. 631 * 632 * The fourth parameter is an optional structure specifying advanced OpenGL 633 * context settings such as antialiasing, depth-buffer bits, etc. 634 * 635 * Params: 636 * mode = Video mode to use (defines the width, height and depth of the 637 * rendering area of the window) 638 * title = Title of the window 639 * style = Window style, a bitwise OR combination of Style enumerators 640 * settings = Additional settings for the underlying OpenGL context 641 * 642 * Deprecated: Use the version of create that takes a 'const(dchar)[]'. 643 */ 644 deprecated("Use the version of create that takes a 'const(dchar)[]'.") 645 override void create(VideoMode mode, const(char)[] title, Style style = Style.DefaultStyle, ContextSettings settings = ContextSettings.init) 646 { 647 import std.utf: toUTF32; 648 auto convertedTitle = toUTF32(title); 649 sfRenderWindow_createFromSettings(sfPtr, mode.width, mode.height, mode.bitsPerPixel, convertedTitle.ptr, convertedTitle.length, style, settings.depthBits, settings.stencilBits, settings.antialiasingLevel, settings.majorVersion, settings.minorVersion); 650 651 } 652 653 /// ditto 654 override void create(VideoMode mode, const(wchar)[] title, Style style = Style.DefaultStyle, ContextSettings settings = ContextSettings.init) 655 { 656 import std.utf: toUTF32; 657 auto convertedTitle = toUTF32(title); 658 sfRenderWindow_createFromSettings(sfPtr, mode.width, mode.height, mode.bitsPerPixel, convertedTitle.ptr, convertedTitle.length, style, settings.depthBits, settings.stencilBits, settings.antialiasingLevel, settings.majorVersion, settings.minorVersion); 659 660 } 661 662 /** 663 * Create (or recreate) the window. 664 * 665 * If the window was already created, it closes it first. If style contains 666 * Window.Style.Fullscreen, then mode must be a valid video mode. 667 * 668 * The fourth parameter is an optional structure specifying advanced OpenGL 669 * context settings such as antialiasing, depth-buffer bits, etc. 670 * 671 * Params: 672 * mode = Video mode to use (defines the width, height and depth of the 673 * rendering area of the window) 674 * title = Title of the window 675 * style = Window style, a bitwise OR combination of Style enumerators 676 * settings = Additional settings for the underlying OpenGL context 677 */ 678 override void create(VideoMode mode, const(dchar)[] title, Style style = Style.DefaultStyle, ContextSettings settings = ContextSettings.init) 679 { 680 sfRenderWindow_createFromSettings(sfPtr, mode.width, mode.height, mode.bitsPerPixel, title.ptr, title.length, style, settings.depthBits, settings.stencilBits, settings.antialiasingLevel, settings.majorVersion, settings.minorVersion); 681 } 682 683 /** 684 * Create (or recreate) the window from an existing control. 685 * 686 * Use this function if you want to create an OpenGL rendering area into an 687 * already existing control. If the window was already created, it closes it 688 * first. 689 * 690 * The second parameter is an optional structure specifying advanced OpenGL 691 * context settings such as antialiasing, depth-buffer bits, etc. 692 * 693 * Params: 694 * handle = Platform-specific handle of the control 695 * settings = Additional settings for the underlying OpenGL context 696 */ 697 override void create(WindowHandle handle, ContextSettings settings = ContextSettings.init) 698 { 699 sfRenderWindow_createFromHandle(sfPtr, handle, settings.depthBits,settings.stencilBits, settings.antialiasingLevel, settings.majorVersion, settings.minorVersion); 700 } 701 702 /** 703 * Copy the current contents of the window to an image 704 * 705 * Deprecated: 706 * Use a $(TEXTURE_LINK Texture) and its `Texture.update()` function and 707 * copy its contents into an $(IMAGE_LINK Image) instead. 708 * 709 * This is a slow operation, whose main purpose is to make screenshots of 710 * the application. If you want to update an image with the contents of the 711 * window and then use it for drawing, you should rather use a 712 * $(TEXTURE_LINK Texture) and its `update()` function. You can also draw 713 * things directly to a texture with the $(RENDERTEXTURE_LINK RenderTexture) 714 * class. 715 * 716 * Returns: An Image containing the captured contents. 717 */ 718 deprecated("Use a Texture, its update function, and copy its contents into an Image instead.") 719 Image capture() 720 { 721 return new Image(sfRenderWindow_capture(sfPtr)); 722 } 723 724 /** 725 * Display on screen what has been rendered to the window so far. 726 * 727 * This function is typically called after all OpenGL rendering has been 728 * done for the current frame, in order to show it on screen. 729 */ 730 override void display() 731 { 732 sfRenderWindow_display(sfPtr); 733 } 734 735 /** 736 * Draw a drawable object to the render target. 737 * 738 * Params: 739 * drawable = Object to draw 740 * states = Render states to use for drawing 741 */ 742 void draw(Drawable drawable, RenderStates states = RenderStates.init) 743 { 744 drawable.draw(this,states); 745 } 746 747 /** 748 * Draw primitives defined by an array of vertices. 749 * 750 * Params: 751 * vertices = Array of vertices to draw 752 * type = Type of primitives to draw 753 * states = Render states to use for drawing 754 */ 755 void draw(const(Vertex)[] vertices, PrimitiveType type, RenderStates states = RenderStates.init) 756 { 757 import std.algorithm; 758 759 sfRenderWindow_drawPrimitives(sfPtr, vertices.ptr, cast(uint)min(uint.max, vertices.length), type,states.blendMode.colorSrcFactor, states.blendMode.alphaDstFactor, 760 states.blendMode.colorEquation, states.blendMode.alphaSrcFactor, states.blendMode.alphaDstFactor, states.blendMode.alphaEquation, 761 states.transform.m_matrix.ptr,states.texture?states.texture.sfPtr:null,states.shader?states.shader.sfPtr:null); 762 } 763 764 /** 765 * Tell whether or not the window is open. 766 * 767 * This function returns whether or not the window exists. Note that a 768 * hidden window (`setVisible(false)`) is open (therefore this function would 769 * return true). 770 * 771 * Returns: true if the window is open, false if it has been closed 772 */ 773 override bool isOpen() const 774 { 775 return (sfRenderWindow_isOpen(sfPtr)); 776 } 777 778 /** 779 * Restore the previously saved OpenGL render states and matrices. 780 * 781 * See the description of pushGLStates to get a detailed description of 782 * these functions. 783 */ 784 void popGLStates() 785 { 786 sfRenderWindow_popGLStates(sfPtr); 787 } 788 789 /** 790 * Save the current OpenGL render states and matrices. 791 * 792 * This function can be used when you mix SFML drawing and direct OpenGL 793 * rendering. Combined with PopGLStates, it ensures that: 794 * $(UL 795 * $(LI DSFML's internal states are not messed up by your OpenGL code) 796 * $(LI your OpenGL states are not modified by a call to an SFML function)) 797 * 798 * $(PARA More specifically, it must be used around the code that calls 799 * `draw` functions. 800 * 801 * Note that this function is quite expensive: it saves all the possible 802 * OpenGL states and matrices, even the ones you don't care about.Therefore 803 * it should be used wisely. It is provided for convenience, but the best 804 * results will be achieved if you handle OpenGL states yourself (because 805 * you know which states have really changed, and need to be saved and 806 * restored). Take a look at the `resetGLStates` function if you do so.) 807 */ 808 void pushGLStates() 809 { 810 sfRenderWindow_pushGLStates(sfPtr); 811 } 812 813 /** 814 * Reset the internal OpenGL states so that the target is ready for drawing. 815 * 816 * This function can be used when you mix SFML drawing and direct OpenGL 817 * rendering, if you choose not to use `pushGLStates`/`popGLStates`. It 818 * makes sure that all OpenGL states needed by DSFML are set, so that 819 * subsequent `draw()` calls will work as expected. 820 */ 821 void resetGLStates() 822 { 823 sfRenderWindow_resetGLStates(sfPtr); 824 } 825 826 /** 827 * Pop the event on top of the event queue, if any, and return it. 828 * 829 * This function is not blocking: if there's no pending event then it will 830 * return false and leave event unmodified. Note that more than one event 831 * may be present in the event queue, thus you should always call this 832 * function in a loop to make sure that you process every pending event. 833 * 834 * Params: 835 * event = Event to be returned 836 * 837 * Returns: true if an event was returned, or false if the event queue was 838 * empty. 839 */ 840 override bool pollEvent(ref Event event) 841 { 842 return (sfRenderWindow_pollEvent(sfPtr, &event)); 843 } 844 845 /** 846 * Wait for an event and return it. 847 * 848 * This function is blocking: if there's no pending event then it will wait 849 * until an event is received. After this function returns (and no error 850 * occured), the event object is always valid and filled properly. This 851 * function is typically used when you have a thread that is dedicated to 852 * events handling: you want to make this thread sleep as long as no new 853 * event is received. 854 * 855 * Params: 856 * event = Event to be returned 857 * 858 * Returns: false if any error occurred. 859 */ 860 override bool waitEvent(ref Event event) 861 { 862 return (sfRenderWindow_waitEvent(sfPtr, &event)); 863 } 864 865 //TODO: Consider adding these methods. 866 //void onCreate 867 //void onResize 868 869 override protected Vector2i getMousePosition()const 870 { 871 Vector2i temp; 872 sfMouse_getPositionRenderWindow(sfPtr, &temp.x, &temp.y); 873 return temp; 874 } 875 876 //TODO: Fix these names or something. 877 override protected void setMousePosition(Vector2i pos) const 878 { 879 sfMouse_setPositionRenderWindow(pos.x, pos.y, sfPtr); 880 } 881 882 //let's Texture have a way to get the sfPtr of a regular window. 883 package static void* windowPointer(const(Window) window) 884 { 885 return getWindowPointer(window); 886 } 887 } 888 889 unittest 890 { 891 version(DSFML_Unittest_Graphics) 892 { 893 import std.stdio; 894 import dsfml.graphics.image; 895 import dsfml.system.clock; 896 import dsfml.graphics.sprite; 897 898 writeln("Unit test for RenderWindow"); 899 900 //constructor 901 auto window = new RenderWindow(VideoMode(800,600),"Test Window"); 902 903 //perform each window call 904 Vector2u windowSize = window.size; 905 906 windowSize.x = 1000; 907 windowSize.y = 1000; 908 909 window.size = windowSize; 910 911 Vector2i windowPosition = window.position; 912 913 windowPosition.x = 100; 914 windowPosition.y = 100; 915 916 window.position = windowPosition; 917 918 window.setTitle("thing");//uses the first set title 919 920 window.setTitle("素晴らしい !"d);//forces the dstring override and uses utf-32 921 922 window.setActive(true); 923 924 window.setJoystickThreshhold(1); 925 926 window.setVisible(true); 927 928 window.setFramerateLimit(60); 929 930 window.setMouseCursorVisible(true); 931 932 window.setVerticalSyncEnabled(true); 933 934 auto settings = window.getSettings(); 935 936 auto image = new Image(); 937 image.loadFromFile("res/TestImage.png"); 938 939 window.setIcon(image.getSize().x,image.getSize().x,image.getPixelArray()); 940 941 auto texture = new Texture(); 942 943 texture.loadFromImage(image); 944 945 auto sprite = new Sprite(texture); 946 947 auto clock = new Clock(); 948 949 while(window.isOpen()) 950 { 951 Event event; 952 if(window.pollEvent(event)) 953 { 954 //no events 955 } 956 957 if(clock.getElapsedTime().asSeconds() > 1) 958 { 959 window.close(); 960 } 961 962 window.clear(); 963 964 window.draw(sprite); 965 966 window.display(); 967 } 968 969 writeln(); 970 } 971 } 972 973 package extern(C) struct sfRenderWindow; 974 975 private extern(C): 976 977 //Construct a new render window 978 sfRenderWindow* sfRenderWindow_construct(); 979 980 //Construct a new render window from settings 981 sfRenderWindow* sfRenderWindow_constructFromSettings(uint width, uint height, uint bitsPerPixel, const(dchar)* title, size_t titleLength, int style, uint depthBits, uint stencilBits, uint antialiasingLevel, uint majorVersion, uint minorVersion); 982 983 //Construct a render window from an existing control 984 sfRenderWindow* sfRenderWindow_constructFromHandle(WindowHandle handle, uint depthBits, uint stencilBits, uint antialiasingLevel, uint majorVersion, uint minorVersion); 985 986 //Create(or recreate) a new render window from settings 987 void sfRenderWindow_createFromSettings(sfRenderWindow* renderWindow, uint width, uint height, uint bitsPerPixel, const(dchar)* title, size_t titleLength, int style, uint depthBits, uint stencilBits, uint antialiasingLevel, uint majorVersion, uint minorVersion); 988 989 //Create(or recreate) a render window from an existing control 990 void sfRenderWindow_createFromHandle(sfRenderWindow* renderWindow, WindowHandle handle, uint depthBits, uint stencilBits, uint antialiasingLevel, uint majorVersion, uint minorVersion); 991 992 //Destroy an existing render window 993 void sfRenderWindow_destroy(sfRenderWindow* renderWindow); 994 995 //Close a render window (but doesn't destroy the internal data) 996 void sfRenderWindow_close(sfRenderWindow* renderWindow); 997 998 //Tell whether or not a render window is opened 999 bool sfRenderWindow_isOpen(const sfRenderWindow* renderWindow); 1000 1001 //Get the creation settings of a render window 1002 void sfRenderWindow_getSettings(const sfRenderWindow* renderWindow, uint* depthBits, uint* stencilBits, uint* antialiasingLevel, uint* majorVersion, uint* minorVersion); 1003 1004 //Get the event on top of event queue of a render window, if any, and pop it 1005 bool sfRenderWindow_pollEvent(sfRenderWindow* renderWindow, Event* event); 1006 1007 //Wait for an event and return it 1008 bool sfRenderWindow_waitEvent(sfRenderWindow* renderWindow, Event* event); 1009 1010 //Get the position of a render window 1011 void sfRenderWindow_getPosition(const sfRenderWindow* renderWindow, int* x, int* y); 1012 1013 //Change the position of a render window on screen 1014 void sfRenderWindow_setPosition(sfRenderWindow* renderWindow, int x, int y); 1015 1016 //Get the size of the rendering region of a render window 1017 void sfRenderWindow_getSize(const sfRenderWindow* renderWindow, uint* width, uint* height); 1018 1019 //Change the size of the rendering region of a render window 1020 void sfRenderWindow_setSize(sfRenderWindow* renderWindow, int width, int height); 1021 1022 //Change the title of a render window 1023 void sfRenderWindow_setTitle(sfRenderWindow* renderWindow, const(char)* title, size_t titleLength); 1024 1025 //Change the title of a render window (with a UTF-32 string) 1026 void sfRenderWindow_setUnicodeTitle(sfRenderWindow* renderWindow, const(dchar)* title, size_t titleLength); 1027 1028 //Change a render window's icon 1029 void sfRenderWindow_setIcon(sfRenderWindow* renderWindow, uint width, uint height, const ubyte* pixels); 1030 1031 //Show or hide a render window 1032 void sfRenderWindow_setVisible(sfRenderWindow* renderWindow, bool visible); 1033 1034 //Show or hide the mouse cursor on a render window 1035 void sfRenderWindow_setMouseCursorVisible(sfRenderWindow* renderWindow, bool show); 1036 1037 //Enable / disable vertical synchronization on a render window 1038 void sfRenderWindow_setVerticalSyncEnabled(sfRenderWindow* renderWindow, bool enabled); 1039 1040 //Enable or disable automatic key-repeat for keydown events 1041 void sfRenderWindow_setKeyRepeatEnabled(sfRenderWindow* renderWindow, bool enabled); 1042 1043 //Activate or deactivate a render window as the current target for rendering 1044 bool sfRenderWindow_setActive(sfRenderWindow* renderWindow, bool active); 1045 1046 //Display a render window on screen 1047 void sfRenderWindow_display(sfRenderWindow* renderWindow); 1048 1049 //Limit the framerate to a maximum fixed frequency for a render window 1050 void sfRenderWindow_setFramerateLimit(sfRenderWindow* renderWindow, uint limit); 1051 1052 //Change the joystick threshold, ie. the value below which no move event will be generated 1053 void sfRenderWindow_setJoystickThreshold(sfRenderWindow* renderWindow, float threshold); 1054 1055 //Retrieve the OS-specific handle of a render window 1056 WindowHandle sfRenderWindow_getSystemHandle(const sfRenderWindow* renderWindow); 1057 1058 //Clear a render window with the given color 1059 void sfRenderWindow_clear(sfRenderWindow* renderWindow, ubyte r, ubyte g, ubyte b, ubyte a); 1060 1061 //Change the current active view of a render window 1062 void sfRenderWindow_setView(sfRenderWindow* renderWindow, float centerX, float centerY, float sizeX, 1063 float sizeY, float rotation, float viewportLeft, float viewportTop, float viewportWidth, 1064 float viewportHeight); 1065 1066 //Get the current active view of a render window 1067 void sfRenderWindow_getView(const sfRenderWindow* renderWindow, float* centerX, float* centerY, float* sizeX, 1068 float* sizeY, float* rotation, float* viewportLeft, float* viewportTop, float* viewportWidth, 1069 float* viewportHeight); 1070 1071 //Get the default view of a render window 1072 void sfRenderWindow_getDefaultView(const sfRenderWindow* renderWindow, float* centerX, float* centerY, float* sizeX, 1073 float* sizeY, float* rotation, float* viewportLeft, float* viewportTop, float* viewportWidth, 1074 float* viewportHeight); 1075 1076 //Draw primitives defined by an array of vertices to a render window 1077 void sfRenderWindow_drawPrimitives(sfRenderWindow* renderWindow,const (void)* vertices, uint vertexCount, int type, int colorSrcFactor, int colorDstFactor, int colorEquation, 1078 int alphaSrcFactor, int alphaDstFactor, int alphaEquation, const (float)* transform, const (sfTexture)* texture, const (sfShader)* shader); 1079 1080 //Save the current OpenGL render states and matrices 1081 void sfRenderWindow_pushGLStates(sfRenderWindow* renderWindow); 1082 1083 //Restore the previously saved OpenGL render states and matrices 1084 void sfRenderWindow_popGLStates(sfRenderWindow* renderWindow); 1085 1086 //Reset the internal OpenGL states so that the target is ready for drawing 1087 void sfRenderWindow_resetGLStates(sfRenderWindow* renderWindow); 1088 1089 //Copy the current contents of a render window to an image 1090 sfImage* sfRenderWindow_capture(const sfRenderWindow* renderWindow); 1091 1092 //Get the current position of the mouse relatively to a render-window 1093 void sfMouse_getPositionRenderWindow(const sfRenderWindow* relativeTo, int* x, int* y); 1094 1095 //Set the current position of the mouse relatively to a render-window 1096 void sfMouse_setPositionRenderWindow(int x, int y, const sfRenderWindow* relativeTo);