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