Skip to main content

chaining effects

5 replies [Last post]
billg
Offline
Joined: 2008-02-03
Points: 0

Hello,

I feel like I am missing something obvious regarding applying multiple effects to a node.

For example, if I wanted to apply a drop shadow and a reflection to a circle here is what I have been doing:

Reflection reflection = new Reflection( );
SGEffect sgReflection = new SGEffect( );
sgReflection.setEffect( reflection );

DropShadow dropShadow = new DropShadow( );
SGEffect sgShadow = new SGEffect( );
sgShadow.setEffect( dropShadow );

sgReflection.setChild( sgShadow );
sgShadow.setChild( myCircleHere );

This does work, but ideally, I would like to just add multiple effects to a node, a la:

FXShape shape = new FXShape();
shape.setShape(circle);
shape.addEffect(dropShadow);
shape.addEffect(reflection);

Or, possibly passing in an effect and an effect index / sequence (or something like that). I'm sure there is a good reason why it does not work like this, but if anyone has any suggestions on a better way to implement multiple effects please let me know.

Thanks in advance,
Bill

Reply viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.
billg
Offline
Joined: 2008-02-03
Points: 0

Hi Chris,

Thanks for your feedback. I do like the idea of chaining effects through their input source, however, as I'm sure you know, not all Effects have inputs (e.g. DropShadow, InnerShadow), which is a little too limiting for what I am trying to build (dynamically add any number of Effects to a node).

I guess if I could make a request for the API, it would be either modify the Effects class structure so they can more be easily linked together (regardless of the effect), or to create some sort of CompoundEffect class that extends Effect but allows you to build an indexed list of effects that render their corresponding node. The latter is the option is what I am leaning towards implementing myself unless an easier solution presents itself (feedback welcomed).

Also, I would like to second Jim's request for allowing negative offsets for the reflection positioning. I think it is going to be necessary for correctly positioning in relation to compound nodes (I also ran into a problem when I tried to add a refection effect to a node that was both drawing a shape ("its border") as well as filling it (the border seemed to be causing the reflection offset)).

Thanks again for the feedback.
Bill

Chris Campbell

Hi Bill,

DropShadow and InnerShadow were anomalies, but only temporarily. I was
originally hesitating to add (and generally being lazy about) inputs for
these, because the default inputs are carefully chosen to provide
high-quality results under any transform. But I can also imagine that
there are many cases where you'd want to provide a single input to these
effects and have them just do the "reasonable" thing. So to that end,
I've gone ahead and added new constructors/methods to DropShadow and
InnerShadow so that the inputs are configurable. (These were the last
holdouts to not have proper configurable input support.)

Also note that inputs can be changed after construction time. All
Effects that can take an input already have one or more set*Input()
methods. I think this system is easy to use and flexible enough to
allow for chaining effects together in the desired order. If you play
around with these set*Input() methods for awhile and still think there
is a simpler way to specify effect chaining, please feel free to offer
suggestions. We're all ears.

I've also gone ahead and changed Reflection to allow for negative topOffset.

Thanks for all this feedback. Clearly it makes a difference :)

Thanks,
Chris

scenario@javadesktop.org wrote:
> Hi Chris,
>
> Thanks for your feedback. I do like the idea of chaining effects through their input source, however, as I'm sure you know, not all Effects have inputs (e.g. DropShadow, InnerShadow), which is a little too limiting for what I am trying to build (dynamically add any number of Effects to a node).
>
> I guess if I could make a request for the API, it would be either modify the Effects class structure so they can more be easily linked together (regardless of the effect), or to create some sort of CompoundEffect class that extends Effect but allows you to build an indexed list of effects that render their corresponding node. The latter is the option is what I am leaning towards implementing myself unless an easier solution presents itself (feedback welcomed).
>
> Also, I would like to second Jim's request for allowing negative offsets for the reflection positioning. I think it is going to be necessary for correctly positioning in relation to compound nodes (I also ran into a problem when I tried to add a refection effect to a node that was both drawing a shape ("its border") as well as filling it (the border seemed to be causing the reflection offset)).
>
> Thanks again for the feedback.
> Bill
> [Message sent by forum member 'billg' (billg)]
>
> http://forums.java.net/jive/thread.jspa?messageID=269861
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: dev-unsubscribe@scenegraph.dev.java.net
> For additional commands, e-mail: dev-help@scenegraph.dev.java.net
>

---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@scenegraph.dev.java.net
For additional commands, e-mail: dev-help@scenegraph.dev.java.net

billg
Offline
Joined: 2008-02-03
Points: 0

Hi Chris,

You are da man!

Thanks again,
Bill

Chris Campbell

Hi Bill,

Effects have a different chaining mechanism than SGNodes. Effects can
be chained together in a tree, similar to SGNodes, but are different in
that an Effect can have many inputs (e.g. a PhongLighting effect that
can take two inputs, the content and a bump map).

You can rework your example code like this:

// shadow is the input to reflect
DropShadow shadow = new DropShadow();
Reflection reflect = new Reflection(shadow);
FXShape circle = new FXShape();
circle.setShape(...);
circle.setEffect(reflect);

Unfortunately this happens to be a tricky case, because the first effect
(the drop shadow) will be padded to account for the shadow, so the
reflection will be positioned quite a bit below the actual content.

Not to mention that it's a little odd visually, and from a basic physics
standpoint, to combine DropShadow and Reflection, but your question is
still very valid :) I hope to write up more of a tutorial about this
stuff in a future blog entry. And the API is still young, so feedback
is welcome.

Thanks,
Chris

scenario@javadesktop.org wrote:
> Hello,
>
> I feel like I am missing something obvious regarding applying multiple effects to a node.
>
> For example, if I wanted to apply a drop shadow and a reflection to a circle here is what I have been doing:
>
> Reflection reflection = new Reflection( );
> SGEffect sgReflection = new SGEffect( );
> sgReflection.setEffect( reflection );
>
> DropShadow dropShadow = new DropShadow( );
> SGEffect sgShadow = new SGEffect( );
> sgShadow.setEffect( dropShadow );
>
> sgReflection.setChild( sgShadow );
> sgShadow.setChild( myCircleHere );
>
> This does work, but ideally, I would like to just add multiple effects to a node, a la:
>
> FXShape shape = new FXShape();
> shape.setShape(circle);
> shape.addEffect(dropShadow);
> shape.addEffect(reflection);
>
> Or, possibly passing in an effect and an effect index / sequence (or something like that). I'm sure there is a good reason why it does not work like this, but if anyone has any suggestions on a better way to implement multiple effects please let me know.
>
> Thanks in advance,
> Bill
> [Message sent by forum member 'billg' (billg)]
>
> http://forums.java.net/jive/thread.jspa?messageID=269635
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: dev-unsubscribe@scenegraph.dev.java.net
> For additional commands, e-mail: dev-help@scenegraph.dev.java.net
>

---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@scenegraph.dev.java.net
For additional commands, e-mail: dev-help@scenegraph.dev.java.net

Jim Graham

Perhaps Reflection should allow a negative topoffset (not normally
useful, but would help in a case like this)?

...jim

Chris Campbell wrote:
> Hi Bill,
>
> Effects have a different chaining mechanism than SGNodes. Effects can
> be chained together in a tree, similar to SGNodes, but are different in
> that an Effect can have many inputs (e.g. a PhongLighting effect that
> can take two inputs, the content and a bump map).
>
> You can rework your example code like this:
>
> // shadow is the input to reflect
> DropShadow shadow = new DropShadow();
> Reflection reflect = new Reflection(shadow);
> FXShape circle = new FXShape();
> circle.setShape(...);
> circle.setEffect(reflect);
>
> Unfortunately this happens to be a tricky case, because the first effect
> (the drop shadow) will be padded to account for the shadow, so the
> reflection will be positioned quite a bit below the actual content.
>
> Not to mention that it's a little odd visually, and from a basic physics
> standpoint, to combine DropShadow and Reflection, but your question is
> still very valid :) I hope to write up more of a tutorial about this
> stuff in a future blog entry. And the API is still young, so feedback
> is welcome.
>
> Thanks,
> Chris
>
>
> scenario@javadesktop.org wrote:
>> Hello,
>>
>> I feel like I am missing something obvious regarding applying multiple
>> effects to a node.
>>
>> For example, if I wanted to apply a drop shadow and a reflection to a
>> circle here is what I have been doing:
>>
>> Reflection reflection = new Reflection( );
>> SGEffect sgReflection = new SGEffect( );
>> sgReflection.setEffect( reflection );
>>
>> DropShadow dropShadow = new DropShadow( );
>> SGEffect sgShadow = new SGEffect( );
>> sgShadow.setEffect( dropShadow );
>>
>> sgReflection.setChild( sgShadow );
>> sgShadow.setChild( myCircleHere );
>>
>> This does work, but ideally, I would like to just add multiple effects
>> to a node, a la:
>>
>> FXShape shape = new FXShape();
>> shape.setShape(circle);
>> shape.addEffect(dropShadow);
>> shape.addEffect(reflection);
>>
>> Or, possibly passing in an effect and an effect index / sequence (or
>> something like that). I'm sure there is a good reason why it does not
>> work like this, but if anyone has any suggestions on a better way to
>> implement multiple effects please let me know.
>>
>> Thanks in advance,
>> Bill
>> [Message sent by forum member 'billg' (billg)]
>>
>> http://forums.java.net/jive/thread.jspa?messageID=269635
>>
>> ---------------------------------------------------------------------
>> To unsubscribe, e-mail: dev-unsubscribe@scenegraph.dev.java.net
>> For additional commands, e-mail: dev-help@scenegraph.dev.java.net
>>
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: dev-unsubscribe@scenegraph.dev.java.net
> For additional commands, e-mail: dev-help@scenegraph.dev.java.net
>

---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@scenegraph.dev.java.net
For additional commands, e-mail: dev-help@scenegraph.dev.java.net