Spec-Zone .ru
спецификации, руководства, описания, API
|
001/* 002 * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved. 003 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 004 * 005 * This code is free software; you can redistribute it and/or modify it 006 * under the terms of the GNU General Public License version 2 only, as 007 * published by the Free Software Foundation. Oracle designates this 008 * particular file as subject to the "Classpath" exception as provided 009 * by Oracle in the LICENSE file that accompanied this code. 010 * 011 * This code is distributed in the hope that it will be useful, but WITHOUT 012 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 013 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 014 * version 2 for more details (a copy is included in the LICENSE file that 015 * accompanied this code). 016 * 017 * You should have received a copy of the GNU General Public License version 018 * 2 along with this work; if not, write to the Free Software Foundation, 019 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 020 * 021 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 022 * or visit www.oracle.com if you need additional information or have any 023 * questions. 024 */ 025 026package javafx.scene.effect; 027 028import javafx.beans.property.BooleanProperty; 029import javafx.beans.property.DoubleProperty; 030import javafx.beans.property.DoublePropertyBase; 031import javafx.beans.property.ObjectProperty; 032import javafx.beans.property.ObjectPropertyBase; 033import javafx.beans.property.SimpleBooleanProperty; 034import javafx.scene.paint.Color; 035 036import com.sun.javafx.Utils; 037import com.sun.javafx.tk.Toolkit; 038 039/** 040 * The abstract base class for all light implementations. 041 */ 042public abstract class Light { 043 044 /** 045 * Creates a new Light. 046 */ 047 protected Light() { 048 impl_markDirty(); 049 } 050 051 abstract com.sun.scenario.effect.light.Light impl_createImpl(); 052 private com.sun.scenario.effect.light.Light peer; 053 054 com.sun.scenario.effect.light.Light impl_getImpl() { 055 if (peer == null) { 056 peer = impl_createImpl(); 057 } 058 return peer; 059 } 060 /** 061 * The color of the light source. 062 * <pre> 063 * Min: n/a 064 * Max: n/a 065 * Default: Color.WHITE 066 * Identity: n/a 067 * </pre> 068 * @defaultValue WHITE 069 */ 070 private ObjectProperty<Color> color; 071 072 public final void setColor(Color value) { 073 colorProperty().set(value); 074 } 075 076 public final Color getColor() { 077 return color == null ? Color.WHITE : color.get(); 078 } 079 080 public final ObjectProperty<Color> colorProperty() { 081 if (color == null) { 082 color = new ObjectPropertyBase<Color>(Color.WHITE) { 083 084 @Override 085 public void invalidated() { 086 impl_markDirty(); 087 } 088 089 @Override 090 public Object getBean() { 091 return Light.this; 092 } 093 094 @Override 095 public String getName() { 096 return "color"; 097 } 098 }; 099 } 100 return color; 101 } 102 103 void impl_sync() { 104 if (impl_isEffectDirty()) { 105 impl_update(); 106 impl_clearDirty(); 107 } 108 } 109 110 private Color getColorInternal() { 111 Color c = getColor(); 112 return c == null ? Color.WHITE : c; 113 } 114 115 void impl_update() { 116 impl_getImpl().setColor(Toolkit.getToolkit().toColor4f(getColorInternal())); 117 } 118 119 private BooleanProperty effectDirty; 120 121 private void setEffectDirty(boolean value) { 122 effectDirtyProperty().set(value); 123 } 124 125 final BooleanProperty effectDirtyProperty() { 126 if (effectDirty == null) { 127 effectDirty = new SimpleBooleanProperty(this, "effectDirty"); 128 } 129 return effectDirty; 130 } 131 132 boolean impl_isEffectDirty() { 133 return effectDirty == null ? false : effectDirty.get(); 134 } 135 136 final void impl_markDirty() { 137 setEffectDirty(true); 138 } 139 140 final void impl_clearDirty() { 141 setEffectDirty(false); 142 } 143 144 /** 145 * Represents a distant light source. 146 * 147 * <p> 148 * Example: 149 * <pre><code> 150 * Light.Distant light = new Light.Distant(); 151 * light.setAzimuth(45.0); 152 * light.setElevation(30.0); 153 * 154 * Lighting lighting = new Lighting(); 155 * lighting.setLight(light); 156 * lighting.setSurfaceScale(5.0); 157 * 158 * Text text = new Text(); 159 * text.setText("Distant"); 160 * text.setFill(Color.STEELBLUE); 161 * text.setFont(Font.font("null", FontWeight.BOLD, 80)); 162 * text.setX(10.0f); 163 * text.setY(10.0f); 164 * text.setTextOrigin(VPos.TOP); 165 * text.setEffect(lighting); 166 * 167 * Rectangle rect = new Rectangle(300,150); 168 * rect.setFill(Color.ALICEBLUE); 169 * rect.setEffect(lighting); 170 * </pre></code> 171 * 172 * <p> The code above produces the following: </p> 173 * <p> <img src="doc-files/lightdistant.png"/> </p> 174 */ 175 public static class Distant extends Light { 176 /** 177 * Creates a new instance of Distant light with default parameters. 178 */ 179 public Distant() {} 180 181 /** 182 * Creates a new instance of Distant light with the specified azimuth, 183 * elevation, and color. 184 * @param azimuth the azimuth of the light 185 * @param elevation the elevation of the light 186 * @param color the color of the light 187 */ 188 public Distant(double azimuth, double elevation, Color color) { 189 setAzimuth(azimuth); 190 setElevation(elevation); 191 setColor(color); 192 } 193 194 @Override 195 com.sun.scenario.effect.light.DistantLight impl_createImpl() { 196 return new com.sun.scenario.effect.light.DistantLight(); 197 } 198 /** 199 * The azimuth of the light. The azimuth is the direction angle 200 * for the light source on the XY plane, in degrees. 201 * <pre> 202 * Min: n/a 203 * Max: n/a 204 * Default: 45.0 205 * Identity: n/a 206 * </pre> 207 * @defaultValue 45.0 208 */ 209 private DoubleProperty azimuth; 210 211 public final void setAzimuth(double value) { 212 azimuthProperty().set(value); 213 } 214 215 public final double getAzimuth() { 216 return azimuth == null ? 45 : azimuth.get(); 217 } 218 219 public final DoubleProperty azimuthProperty() { 220 if (azimuth == null) { 221 azimuth = new DoublePropertyBase(45) { 222 223 @Override 224 public void invalidated() { 225 impl_markDirty(); 226 } 227 228 @Override 229 public Object getBean() { 230 return Distant.this; 231 } 232 233 @Override 234 public String getName() { 235 return "azimuth"; 236 } 237 }; 238 } 239 return azimuth; 240 } 241 /** 242 * The elevation of the light. The elevation is the 243 * direction angle for the light source on the YZ plane, in degrees. 244 * <pre> 245 * Min: n/a 246 * Max: n/a 247 * Default: 45.0 248 * Identity: n/a 249 * </pre> 250 * @defaultValue 45.0 251 */ 252 private DoubleProperty elevation; 253 254 public final void setElevation(double value) { 255 elevationProperty().set(value); 256 } 257 258 public final double getElevation() { 259 return elevation == null ? 45 : elevation.get(); 260 } 261 262 public final DoubleProperty elevationProperty() { 263 if (elevation == null) { 264 elevation = new DoublePropertyBase(45) { 265 266 @Override 267 public void invalidated() { 268 impl_markDirty(); 269 } 270 271 @Override 272 public Object getBean() { 273 return Distant.this; 274 } 275 276 @Override 277 public String getName() { 278 return "elevation"; 279 } 280 }; 281 } 282 return elevation; 283 } 284 285 @Override 286 void impl_update() { 287 super.impl_update(); 288 com.sun.scenario.effect.light.DistantLight peer = 289 (com.sun.scenario.effect.light.DistantLight) impl_getImpl(); 290 peer.setAzimuth((float) getAzimuth()); 291 peer.setElevation((float) getElevation()); 292 } 293 } 294 295 /** 296 * Represents a light source at a given position in 3D space. 297 * 298 * <p> 299 * Example: 300 * <pre><code> 301 * Light.Point light = new Light.Point(); 302 * light.setX(100); 303 * light.setY(100); 304 * light.setZ(50); 305 * 306 * Lighting lighting = new Lighting(); 307 * lighting.setLight(light); 308 * lighting.setSurfaceScale(5.0); 309 * 310 * Text text = new Text(); 311 * text.setText("Point"); 312 * text.setFill(Color.STEELBLUE); 313 * text.setFont(Font.font(null, FontWeight.BOLD, 80)); 314 * text.setX(10.0); 315 * text.setY(10.0); 316 * text.setTextOrigin(VPos.TOP); 317 * 318 * Rectangle rect = new Rectangle(250, 150); 319 * rect.setFill(Color.ALICEBLUE); 320 * rect.setEffect(lighting); 321 * text.setEffect(lighting); 322 * </pre></code> 323 * 324 * <p> The code above produces the following: </p> 325 * <p> <img src="doc-files/lightpoint.png"/> </p> 326 */ 327 public static class Point extends Light { 328 /** 329 * Creates a new instance of Point light with default parameters. 330 */ 331 public Point() {} 332 333 /** 334 * Creates a new instance of Point light with the specified x, y, x, and 335 * color. 336 * @param x the x coordinate of the light position 337 * @param y the y coordinate of the light position 338 * @param z the z coordinate of the light position 339 * @param color the color of the light 340 */ 341 public Point(double x, double y, double z, Color color) { 342 setX(x); 343 setY(y); 344 setZ(z); 345 setColor(color); 346 } 347 348 /** 349 * @treatAsPrivate implementation detail 350 * @deprecated This is an internal API that is not intended for use and will be removed in the next version 351 */ 352 @Deprecated 353 @Override 354 com.sun.scenario.effect.light.PointLight impl_createImpl() { 355 return new com.sun.scenario.effect.light.PointLight(); 356 } 357 /** 358 * The x coordinate of the light position. 359 * <pre> 360 * Min: n/a 361 * Max: n/a 362 * Default: 0.0 363 * Identity: n/a 364 * </pre> 365 * @defaultValue 0.0 366 */ 367 private DoubleProperty x; 368 369 public final void setX(double value) { 370 xProperty().set(value); 371 } 372 373 public final double getX() { 374 return x == null ? 0 : x.get(); 375 } 376 377 public final DoubleProperty xProperty() { 378 if (x == null) { 379 x = new DoublePropertyBase() { 380 381 @Override 382 public void invalidated() { 383 impl_markDirty(); 384 } 385 386 @Override 387 public Object getBean() { 388 return Point.this; 389 } 390 391 @Override 392 public String getName() { 393 return "x"; 394 } 395 }; 396 } 397 return x; 398 } 399 /** 400 * The y coordinate of the light position. 401 * <pre> 402 * Min: n/a 403 * Max: n/a 404 * Default: 0.0 405 * Identity: n/a 406 * </pre> 407 * @defaultValue 0.0 408 */ 409 private DoubleProperty y; 410 411 public final void setY(double value) { 412 yProperty().set(value); 413 } 414 415 public final double getY() { 416 return y == null ? 0 : y.get(); 417 } 418 419 public final DoubleProperty yProperty() { 420 if (y == null) { 421 y = new DoublePropertyBase() { 422 423 @Override 424 public void invalidated() { 425 impl_markDirty(); 426 } 427 428 @Override 429 public Object getBean() { 430 return Point.this; 431 } 432 433 @Override 434 public String getName() { 435 return "y"; 436 } 437 }; 438 } 439 return y; 440 } 441 /** 442 * The z coordinate of the light position. 443 * <pre> 444 * Min: n/a 445 * Max: n/a 446 * Default: 0.0 447 * Identity: n/a 448 * </pre> 449 * @defaultValue 0.0 450 */ 451 private DoubleProperty z; 452 453 public final void setZ(double value) { 454 zProperty().set(value); 455 } 456 457 public final double getZ() { 458 return z == null ? 0 : z.get(); 459 } 460 461 public final DoubleProperty zProperty() { 462 if (z == null) { 463 z = new DoublePropertyBase() { 464 465 @Override 466 public void invalidated() { 467 impl_markDirty(); 468 } 469 470 @Override 471 public Object getBean() { 472 return Point.this; 473 } 474 475 @Override 476 public String getName() { 477 return "z"; 478 } 479 }; 480 } 481 return z; 482 } 483 484 @Override 485 void impl_update() { 486 super.impl_update(); 487 com.sun.scenario.effect.light.PointLight peer = 488 (com.sun.scenario.effect.light.PointLight) impl_getImpl(); 489 peer.setX((float) getX()); 490 peer.setY((float) getY()); 491 peer.setZ((float) getZ()); 492 } 493 } 494 495 /** 496 * Represents a spot light source at a given position in 3D space, with 497 * configurable direction and focus. 498 * 499 * <p> 500 * Example: 501 * <pre><code> 502 * Light.Spot light = new Light.Spot(); 503 * light.setX(150); 504 * light.setY(100); 505 * light.setZ(80); 506 * light.setPointsAtX(0); 507 * light.setPointsAtY(0); 508 * light.setPointsAtZ(-50); 509 * light.setSpecularExponent(2); 510 * 511 * Lighting lighting = new Lighting(); 512 * lighting.setLight(light); 513 * lighting.setSurfaceScale(5.0); 514 * 515 * Text text = new Text(); 516 * text.setText("Spot"); 517 * text.setFill(Color.STEELBLUE); 518 * text.setFont(Font.font(null, FontWeight.BOLD, 80)); 519 * text.setX(10.0); 520 * text.setY(10.0); 521 * text.setTextOrigin(VPos.TOP); 522 * text.setEffect(lighting); 523 * 524 * Rectangle rect = new Rectangle(200, 150); 525 * rect.setFill(Color.ALICEBLUE); 526 * rect.setEffect(lighting); 527 * </pre></code> 528 * 529 * <p> The code above produces the following: </p> 530 * <p> <img src="doc-files/lightspot.png"/> </p> 531 * 532 */ 533 public static class Spot extends Light.Point { 534 /** 535 * Creates a new instance of Spot light with default parameters. 536 */ 537 public Spot() {} 538 539 /** 540 * Creates a new instance of Spot light with the specified x, y, z, 541 * specularExponent, and color. 542 * @param x the x coordinate of the light position 543 * @param y the y coordinate of the light position 544 * @param z the z coordinate of the light position 545 * @param specularExponent the specular exponent, which controls the 546 * focus of the light source 547 * @param color the color of the light 548 */ 549 public Spot(double x, double y, double z, double specularExponent, Color color) { 550 setX(x); 551 setY(y); 552 setZ(z); 553 setSpecularExponent(specularExponent); 554 setColor(color); 555 } 556 557 /** 558 * @treatAsPrivate implementation detail 559 * @deprecated This is an internal API that is not intended for use and will be removed in the next version 560 */ 561 @Deprecated 562 @Override 563 com.sun.scenario.effect.light.SpotLight impl_createImpl() { 564 return new com.sun.scenario.effect.light.SpotLight(); 565 } 566 /** 567 * The x coordinate of the direction vector for this light. 568 * <pre> 569 * Min: n/a 570 * Max: n/a 571 * Default: 0.0 572 * Identity: n/a 573 * </pre> 574 * @defaultValue 0.0 575 */ 576 private DoubleProperty pointsAtX; 577 578 public final void setPointsAtX(double value) { 579 pointsAtXProperty().set(value); 580 } 581 582 public final double getPointsAtX() { 583 return pointsAtX == null ? 0 : pointsAtX.get(); 584 } 585 586 public final DoubleProperty pointsAtXProperty() { 587 if (pointsAtX == null) { 588 pointsAtX = new DoublePropertyBase() { 589 590 @Override 591 public void invalidated() { 592 impl_markDirty(); 593 } 594 595 @Override 596 public Object getBean() { 597 return Spot.this; 598 } 599 600 @Override 601 public String getName() { 602 return "pointsAtX"; 603 } 604 }; 605 } 606 return pointsAtX; 607 } 608 /** 609 * The y coordinate of the direction vector for this light. 610 * <pre> 611 * Min: n/a 612 * Max: n/a 613 * Default: 0.0 614 * Identity: n/a 615 * </pre> 616 * @defaultValue 0.0 617 */ 618 private DoubleProperty pointsAtY; 619 620 public final void setPointsAtY(double value) { 621 pointsAtYProperty().set(value); 622 } 623 624 public final double getPointsAtY() { 625 return pointsAtY == null ? 0 : pointsAtY.get(); 626 } 627 628 public final DoubleProperty pointsAtYProperty() { 629 if (pointsAtY == null) { 630 pointsAtY = new DoublePropertyBase() { 631 632 @Override 633 public void invalidated() { 634 impl_markDirty(); 635 } 636 637 @Override 638 public Object getBean() { 639 return Spot.this; 640 } 641 642 @Override 643 public String getName() { 644 return "pointsAtY"; 645 } 646 }; 647 } 648 return pointsAtY; 649 } 650 /** 651 * The z coordinate of the direction vector for this light. 652 * <pre> 653 * Min: n/a 654 * Max: n/a 655 * Default: 0.0 656 * Identity: n/a 657 * </pre> 658 * @defaultValue 0.0 659 */ 660 private DoubleProperty pointsAtZ; 661 662 public final void setPointsAtZ(double value) { 663 pointsAtZProperty().set(value); 664 } 665 666 public final double getPointsAtZ() { 667 return pointsAtZ == null ? 0 : pointsAtZ.get(); 668 } 669 670 public final DoubleProperty pointsAtZProperty() { 671 if (pointsAtZ == null) { 672 pointsAtZ = new DoublePropertyBase() { 673 674 @Override 675 public void invalidated() { 676 impl_markDirty(); 677 } 678 679 @Override 680 public Object getBean() { 681 return Spot.this; 682 } 683 684 @Override 685 public String getName() { 686 return "pointsAtZ"; 687 } 688 }; 689 } 690 return pointsAtZ; 691 } 692 /** 693 * The specular exponent, which controls the focus of this 694 * light source. 695 * <pre> 696 * Min: 0.0 697 * Max: 4.0 698 * Default: 1.0 699 * Identity: 1.0 700 * </pre> 701 * @defaultValue 1.0 702 */ 703 private DoubleProperty specularExponent; 704 705 public final void setSpecularExponent(double value) { 706 specularExponentProperty().set(value); 707 } 708 709 public final double getSpecularExponent() { 710 return specularExponent == null ? 1 : specularExponent.get(); 711 } 712 713 public final DoubleProperty specularExponentProperty() { 714 if (specularExponent == null) { 715 specularExponent = new DoublePropertyBase(1) { 716 717 @Override 718 public void invalidated() { 719 impl_markDirty(); 720 } 721 722 @Override 723 public Object getBean() { 724 return Spot.this; 725 } 726 727 @Override 728 public String getName() { 729 return "specularExponent"; 730 } 731 }; 732 } 733 return specularExponent; 734 } 735 736 @Override 737 void impl_update() { 738 super.impl_update(); 739 com.sun.scenario.effect.light.SpotLight peer = 740 (com.sun.scenario.effect.light.SpotLight) impl_getImpl(); 741 peer.setPointsAtX((float) getPointsAtX()); 742 peer.setPointsAtY((float) getPointsAtY()); 743 peer.setPointsAtZ((float) getPointsAtZ()); 744 peer.setSpecularExponent((float) Utils.clamp(0, getSpecularExponent(), 4)); 745 } 746 } 747}