Professional Web Applications Themes

Image transition effects - Mac Programming

Anyone have any ideas on how the default mac screen savers do their image transitions (zooming and fading in and out)? It seems to me that they are using OpenGL, and before I go down that route I wanted to make sure there wasn't an easier or better way. Is there any open source code available that does this? I found some code through CocoaDev (FadeToBlack) that uses OpenGL in a screen saver view to fade the screen to black (instead of the standard white). peace out, -gabe...

  1. #1

    Default Image transition effects

    Anyone have any ideas on how the default mac screen savers do their image transitions (zooming and
    fading in and out)? It seems to me that they are using OpenGL, and before I go down that route I
    wanted to make sure there wasn't an easier or better way.

    Is there any open source code available that does this?

    I found some code through CocoaDev (FadeToBlack) that uses OpenGL in a screen saver view to fade the
    screen to black (instead of the standard white).

    peace out,
    -gabe
    Gabriel Guest

  2. #2

    Default Re: Image transition effects

    In article <net>,
    Gabriel Handford <edu> wrote:
     

    I would strongly suspect that it's done through Quartz, which supports
    zooming and transparency. I can't tell you _how_ it's done, though, as
    I'm no expert on the subject.

    You might take a look in:
    <http://developer.apple.com/quartz/>

    <http://developer.apple.com/doentation/GraphicsImaging/Quartz-date.htm
    l>

    The latter link gets you the reference doc that describes the Quartz API
    for C / C++ / Objective-C.


    -- Bert Sierra
    Bert Guest

  3. #3

    Default Re: Image transition effects

    In article <net>,
    Gabriel Handford <edu> wrote:
     

    There are Core Graphics frame buffer calls to fade ALL the displays. If you
    just want to fade some of the displays, there are Core Graphics Frame
    Buffer gamma table calls to do one step.


    Here is a fragment from one of my programsd. This program is still CFM, so
    it has to use a CFM<->Mach-O bridge to get to Core Graphics

    #include <CGDirectDisplay.h>


    /// a convenient struct to represent a gamma "curve"
    struct GammaRec {
    CGGammaValue redMin, redMax, redGamma,
    greenMin, greenMax, greenGamma,
    blueMin, blueMax, blueGamma ;
    };

    namespace {

    // ---------------------------------------------------------------------------
    // € GetLinearGammaRec - helper for CFader
    // ---------------------------------------------------------------------------
    /// store a linear gamma "curve" into outRec.
    void GetLinearGammaRec(GammaRec& outRec){
    outRec.redMin = outRec.greenMin = outRec.blueMin = 0.0;
    outRec.redMax = outRec.greenMax = outRec.blueMax = 1.0;
    outRec.redGamma = outRec.greenGamma = outRec.blueGamma = 1.0;
    }

    // ---------------------------------------------------------------------------
    // € GetGammaRec - helper for CFader
    // ---------------------------------------------------------------------------
    /*! Store the userΉs ColorSync settings as the starting gamma values. */
    void GetGammaRec(CGDirectDisplayID display, GammaRec& outRec){
    ThrowIfOSStatus_(CG::GetDisplayTransferByFormula( display,
    &outRec.redMin, &outRec.redMax, &outRec.redGamma,
    &outRec.greenMin, &outRec.greenMax, &outRec.greenGamma,
    &outRec.blueMin, &outRec.blueMax, &outRec.blueGamma));
    }

    // ---------------------------------------------------------------------------
    // € ToBlack - helper for CFader
    // ---------------------------------------------------------------------------
    /*! Fade by linearly interpolating from the passed in gamma (1.0) to black (0.0). */
    /// Note: Apple has a set of system calls specifically for fading the display. We can't
    /// use those calls, because they fade ALL the displays, not just the stimulus monitor.
    void ToBlack(CGDirectDisplayID display, const GammaRec& inRec, long sleepMicroSecs){
    for(double fadeValue = 1.0; fadeValue >= 0.0; fadeValue -= 0.01 ){
    ThrowIfOSStatus_(CG::SetDisplayTransferByFormula( display,
    inRec.redMin, fadeValue*inRec.redMax, inRec.redGamma,
    inRec.greenMin, fadeValue*inRec.greenMax, inRec.greenGamma,
    inRec.blueMin, fadeValue*inRec.blueMax, inRec.blueGamma));
    CG::usleep(sleepMicroSecs);
    }
    }

    // ---------------------------------------------------------------------------
    // € FromBlack - helper for CFader
    // ---------------------------------------------------------------------------
    /*! Fade by linearly interpolating from black (0.0) to the passed in gamma (1.0). */
    /// Note: Apple has a set of system calls specifically for fading the display. We can't
    /// use them, because they fade ALL the displays, not just the stimulus monitor.
    void FromBlack(CGDirectDisplayID display, const GammaRec& inRec, long sleepMicroSecs){
    for(double fadeValue = 0.0; fadeValue <= 1.0; fadeValue += 0.01 ){
    ThrowIfOSStatus_(CG::SetDisplayTransferByFormula( display,
    inRec.redMin, fadeValue*inRec.redMax, inRec.redGamma,
    inRec.greenMin, fadeValue*inRec.greenMax, inRec.greenGamma,
    inRec.blueMin, fadeValue*inRec.blueMax, inRec.blueGamma)) ;
    CG::usleep(sleepMicroSecs);
    }
    }

    } // end anonymous namespace

    /// CFader - encapsulate CoreGraphics fading from desktop to stimulus and back in this object.
    /// strategy:
    //// We show our stimulus by
    /// (a) we fade from desktop to black, (b) draw our stimulus window, (c) set the display to
    /// linear gamma, then fade up to stimulus.
    ///
    /// We hide our stimulus by:
    /// (a) we fade from stimulus to black, (b) remove our stimulus window, (c) restore the original
    /// gamma curve of the monitor, and fade up from black, revealing the desktop.
    ///
    /// the CFader keeps track of our fade state, and calls the routines defined above to actually do
    /// the work.
    ///
    /// General strategy: There are many layers of function calls here. Layer 3:
    /// our stimulus window, CStimulusForRecordingGL might become visible either
    /// by the caller calling Show() or SetFrameRate(). CStimulusForRecordingGL tells its private CFader
    /// to fade to black, CStimulusForRecordingGL shows itself, then tells its CFader to fade to stimulus.
    /// the CFader handles the case that the CStimulusForRecordingGL is already showing.
    ///
    /// At the end, when CStimulusForRecordingGL is dieing or hiding, it calls its private CFader to
    /// fade to black, CStimulusForRecordingGL hides itself, then tells its CFader to restore the gamma, and
    /// fade up to the desktop.
    ///
    /// Layer 2: CFader in turn, works by calling helper routines like ToBlack() defined in the anonymous namespace.
    ///
    /// Layer 1: those in turn work by calling CFM wrappers for Mach-O system calls. The wrappers are
    /// defined in the "CG" namespace. The wrappers silently no-op if called on Classic.
    ///
    /// Layer 0: the actual system calls. See CRegistryOSX.cp for the Layer 3 defs.
    ///
    /// Layer 4: is the code that calls CStimulusForRecordingGL.
    ///
    /// Note that the CFader object knows only about the CoreGraphics gamma calls. CFader knows nothing
    /// about Quickdraw or OpenGL.
    class CFader {
    private:
    enum FadeState {
    isDesktopE,
    isStimulusE,
    isBlackE
    };
    CGDirectDisplayID mDisplayID;
    GammaRec mOriginal;
    GammaRec mLinear;
    long mStepTime;
    FadeState mFadeState;
    public:
    CFader(CGDirectDisplayID inDisplayID);
    ~CFader();
    void StimulusToBlack() throw();
    void BlackToStimulus() throw();
    void DesktopToBlack() throw();
    void BlackToDesktop() throw();
    private:
    };

    // ---------------------------------------------------------------------------
    // € CFader - constructor
    // ---------------------------------------------------------------------------
    CFader::CFader(CGDirectDisplayID inDisplayID){
    mDisplayID = NULL;
    mStepTime = 4000; // in microseconds.
    mFadeState = isDesktopE;
    if(NULL != inDisplayID){
    mDisplayID = inDisplayID;
    ThrowIfNil_(mDisplayID);
    GetGammaRec(mDisplayID, mOriginal);
    GetLinearGammaRec(mLinear);
    }
    }

    // ---------------------------------------------------------------------------
    // € ~CFader -
    // ---------------------------------------------------------------------------
    //// on destruction, try to leave monitor in the "desktop" state.
    CFader::~CFader(){
    if(NULL != mDisplayID and mFadeState != isDesktopE){
    switch(mFadeState){
    default: StimulusToBlack(); // fall through
    case isBlackE: BlackToDesktop();
    }
    }
    }

    // ---------------------------------------------------------------------------
    // € StimulusToBlack -
    // ---------------------------------------------------------------------------
    /// If we are in the stimulus state, go to the black state.
    /// see comment above class declaration.
    void CFader::StimulusToBlack() throw(){
    if(UEnvironment::IsRunningOSX()){
    #if PP_Target_Carbon
    try{
    if(isStimulusE == mFadeState){
    ToBlack(mDisplayID, mLinear, mStepTime);
    mFadeState = isBlackE;
    }
    }catch(...){ // fading is cosmetic. ignore errors.
    }
    #endif
    }
    }

    // ---------------------------------------------------------------------------
    // € BlackToStimulus -
    // ---------------------------------------------------------------------------
    /// If we are in the black state, go to the stimulus state.
    /// see comment above class declaration.
    void CFader::BlackToStimulus() throw(){
    if(UEnvironment::IsRunningOSX()){
    #if PP_Target_Carbon
    try{
    if(isBlackE == mFadeState){
    FromBlack(mDisplayID, mLinear, mStepTime);
    mFadeState = isStimulusE;
    }
    }catch(...){ // fading is cosmetic. ignore errors.
    }
    #endif
    }
    }


    // ---------------------------------------------------------------------------
    // € DesktopToBlack -
    // ---------------------------------------------------------------------------
    /// If we are in the desktop state, go to the black state.
    /// see comment above class declaration.
    void CFader::DesktopToBlack() throw(){
    if(UEnvironment::IsRunningOSX()){
    #if PP_Target_Carbon
    try{
    if(isDesktopE == mFadeState){
    ToBlack(mDisplayID, mOriginal, mStepTime);
    mFadeState = isBlackE;
    }
    }catch(...){ // fading is cosmetic. ignore errors.
    }
    #endif
    }
    }


    // ---------------------------------------------------------------------------
    // € BlackToDesktop -
    // ---------------------------------------------------------------------------
    /// If we are in the black state, go to the desktop state. This also restores
    /// the original gamma of the monitor, over and above what we stored in GetGamma().
    /// see comment above class declaration.
    void CFader::BlackToDesktop() throw(){
    if(UEnvironment::IsRunningOSX()){
    #if PP_Target_Carbon
    try{
    if(isBlackE == mFadeState){
    FromBlack(mDisplayID, mOriginal, mStepTime);
    CG::DisplayRestoreColorSyncSettings();
    mFadeState = isDesktopE;
    }
    }catch(...){ // fading is cosmetic. ignore errors.
    }
    #endif
    }
    }
    David Guest

  4. #4

    Default Re: Image transition effects

    Thanks for the code example.

    Before I saw this post, to fade an image into view, I used:

    [currentImage compositeToPoint:scaledRect.origin fromRect:sourceRect operation:NSCompositeSourceOver
    fraction:delta];

    with an increasing delta from 0 to 1 using a repeating timer with interval of 0.015 seconds
    (~66/second). It doesn't seem as smooth as the apple screensavers.

    I am going to try to use the Core Graphics directly, do you think this going to be faster (and
    easier on the cpu/gpu)? I'm assuming NSImage uses Core Graphics.. hrmm... I guess I just experiment
    with it...

    -gabe

    David Phillip Oster wrote:
     
    >
    >
    > There are Core Graphics frame buffer calls to fade ALL the displays. If you
    > just want to fade some of the displays, there are Core Graphics Frame
    > Buffer gamma table calls to do one step.
    >
    >
    > Here is a fragment from one of my programsd. This program is still CFM, so
    > it has to use a CFM<->Mach-O bridge to get to Core Graphics
    >
    > #include <CGDirectDisplay.h>
    >
    >
    > /// a convenient struct to represent a gamma "curve"
    > struct GammaRec {
    > CGGammaValue redMin, redMax, redGamma,
    > greenMin, greenMax, greenGamma,
    > blueMin, blueMax, blueGamma ;
    > };
    >
    > namespace {
    >
    > // ---------------------------------------------------------------------------
    > // € GetLinearGammaRec - helper for CFader
    > // ---------------------------------------------------------------------------
    > /// store a linear gamma "curve" into outRec.
    > void GetLinearGammaRec(GammaRec& outRec){
    > outRec.redMin = outRec.greenMin = outRec.blueMin = 0.0;
    > outRec.redMax = outRec.greenMax = outRec.blueMax = 1.0;
    > outRec.redGamma = outRec.greenGamma = outRec.blueGamma = 1.0;
    > }
    >
    > // ---------------------------------------------------------------------------
    > // € GetGammaRec - helper for CFader
    > // ---------------------------------------------------------------------------
    > /*! Store the userΉs ColorSync settings as the starting gamma values. */
    > void GetGammaRec(CGDirectDisplayID display, GammaRec& outRec){
    > ThrowIfOSStatus_(CG::GetDisplayTransferByFormula( display,
    > &outRec.redMin, &outRec.redMax, &outRec.redGamma,
    > &outRec.greenMin, &outRec.greenMax, &outRec.greenGamma,
    > &outRec.blueMin, &outRec.blueMax, &outRec.blueGamma));
    > }
    >
    > // ---------------------------------------------------------------------------
    > // € ToBlack - helper for CFader
    > // ---------------------------------------------------------------------------
    > /*! Fade by linearly interpolating from the passed in gamma (1.0) to black (0.0). */
    > /// Note: Apple has a set of system calls specifically for fading the display. We can't
    > /// use those calls, because they fade ALL the displays, not just the stimulus monitor.
    > void ToBlack(CGDirectDisplayID display, const GammaRec& inRec, long sleepMicroSecs){
    > for(double fadeValue = 1.0; fadeValue >= 0.0; fadeValue -= 0.01 ){
    > ThrowIfOSStatus_(CG::SetDisplayTransferByFormula( display,
    > inRec.redMin, fadeValue*inRec.redMax, inRec.redGamma,
    > inRec.greenMin, fadeValue*inRec.greenMax, inRec.greenGamma,
    > inRec.blueMin, fadeValue*inRec.blueMax, inRec.blueGamma));
    > CG::usleep(sleepMicroSecs);
    > }
    > }
    >
    > // ---------------------------------------------------------------------------
    > // € FromBlack - helper for CFader
    > // ---------------------------------------------------------------------------
    > /*! Fade by linearly interpolating from black (0.0) to the passed in gamma (1.0). */
    > /// Note: Apple has a set of system calls specifically for fading the display. We can't
    > /// use them, because they fade ALL the displays, not just the stimulus monitor.
    > void FromBlack(CGDirectDisplayID display, const GammaRec& inRec, long sleepMicroSecs){
    > for(double fadeValue = 0.0; fadeValue <= 1.0; fadeValue += 0.01 ){
    > ThrowIfOSStatus_(CG::SetDisplayTransferByFormula( display,
    > inRec.redMin, fadeValue*inRec.redMax, inRec.redGamma,
    > inRec.greenMin, fadeValue*inRec.greenMax, inRec.greenGamma,
    > inRec.blueMin, fadeValue*inRec.blueMax, inRec.blueGamma)) ;
    > CG::usleep(sleepMicroSecs);
    > }
    > }
    >
    > } // end anonymous namespace
    >
    > /// CFader - encapsulate CoreGraphics fading from desktop to stimulus and back in this object.
    > /// strategy:
    > //// We show our stimulus by
    > /// (a) we fade from desktop to black, (b) draw our stimulus window, (c) set the display to
    > /// linear gamma, then fade up to stimulus.
    > ///
    > /// We hide our stimulus by:
    > /// (a) we fade from stimulus to black, (b) remove our stimulus window, (c) restore the original
    > /// gamma curve of the monitor, and fade up from black, revealing the desktop.
    > ///
    > /// the CFader keeps track of our fade state, and calls the routines defined above to actually do
    > /// the work.
    > ///
    > /// General strategy: There are many layers of function calls here. Layer 3:
    > /// our stimulus window, CStimulusForRecordingGL might become visible either
    > /// by the caller calling Show() or SetFrameRate(). CStimulusForRecordingGL tells its private CFader
    > /// to fade to black, CStimulusForRecordingGL shows itself, then tells its CFader to fade to stimulus.
    > /// the CFader handles the case that the CStimulusForRecordingGL is already showing.
    > ///
    > /// At the end, when CStimulusForRecordingGL is dieing or hiding, it calls its private CFader to
    > /// fade to black, CStimulusForRecordingGL hides itself, then tells its CFader to restore the gamma, and
    > /// fade up to the desktop.
    > ///
    > /// Layer 2: CFader in turn, works by calling helper routines like ToBlack() defined in the anonymous namespace.
    > ///
    > /// Layer 1: those in turn work by calling CFM wrappers for Mach-O system calls. The wrappers are
    > /// defined in the "CG" namespace. The wrappers silently no-op if called on Classic.
    > ///
    > /// Layer 0: the actual system calls. See CRegistryOSX.cp for the Layer 3 defs.
    > ///
    > /// Layer 4: is the code that calls CStimulusForRecordingGL.
    > ///
    > /// Note that the CFader object knows only about the CoreGraphics gamma calls. CFader knows nothing
    > /// about Quickdraw or OpenGL.
    > class CFader {
    > private:
    > enum FadeState {
    > isDesktopE,
    > isStimulusE,
    > isBlackE
    > };
    > CGDirectDisplayID mDisplayID;
    > GammaRec mOriginal;
    > GammaRec mLinear;
    > long mStepTime;
    > FadeState mFadeState;
    > public:
    > CFader(CGDirectDisplayID inDisplayID);
    > ~CFader();
    > void StimulusToBlack() throw();
    > void BlackToStimulus() throw();
    > void DesktopToBlack() throw();
    > void BlackToDesktop() throw();
    > private:
    > };
    >
    > // ---------------------------------------------------------------------------
    > // € CFader - constructor
    > // ---------------------------------------------------------------------------
    > CFader::CFader(CGDirectDisplayID inDisplayID){
    > mDisplayID = NULL;
    > mStepTime = 4000; // in microseconds.
    > mFadeState = isDesktopE;
    > if(NULL != inDisplayID){
    > mDisplayID = inDisplayID;
    > ThrowIfNil_(mDisplayID);
    > GetGammaRec(mDisplayID, mOriginal);
    > GetLinearGammaRec(mLinear);
    > }
    > }
    >
    > // ---------------------------------------------------------------------------
    > // € ~CFader -
    > // ---------------------------------------------------------------------------
    > //// on destruction, try to leave monitor in the "desktop" state.
    > CFader::~CFader(){
    > if(NULL != mDisplayID and mFadeState != isDesktopE){
    > switch(mFadeState){
    > default: StimulusToBlack(); // fall through
    > case isBlackE: BlackToDesktop();
    > }
    > }
    > }
    >
    > // ---------------------------------------------------------------------------
    > // € StimulusToBlack -
    > // ---------------------------------------------------------------------------
    > /// If we are in the stimulus state, go to the black state.
    > /// see comment above class declaration.
    > void CFader::StimulusToBlack() throw(){
    > if(UEnvironment::IsRunningOSX()){
    > #if PP_Target_Carbon
    > try{
    > if(isStimulusE == mFadeState){
    > ToBlack(mDisplayID, mLinear, mStepTime);
    > mFadeState = isBlackE;
    > }
    > }catch(...){ // fading is cosmetic. ignore errors.
    > }
    > #endif
    > }
    > }
    >
    > // ---------------------------------------------------------------------------
    > // € BlackToStimulus -
    > // ---------------------------------------------------------------------------
    > /// If we are in the black state, go to the stimulus state.
    > /// see comment above class declaration.
    > void CFader::BlackToStimulus() throw(){
    > if(UEnvironment::IsRunningOSX()){
    > #if PP_Target_Carbon
    > try{
    > if(isBlackE == mFadeState){
    > FromBlack(mDisplayID, mLinear, mStepTime);
    > mFadeState = isStimulusE;
    > }
    > }catch(...){ // fading is cosmetic. ignore errors.
    > }
    > #endif
    > }
    > }
    >
    >
    > // ---------------------------------------------------------------------------
    > // € DesktopToBlack -
    > // ---------------------------------------------------------------------------
    > /// If we are in the desktop state, go to the black state.
    > /// see comment above class declaration.
    > void CFader::DesktopToBlack() throw(){
    > if(UEnvironment::IsRunningOSX()){
    > #if PP_Target_Carbon
    > try{
    > if(isDesktopE == mFadeState){
    > ToBlack(mDisplayID, mOriginal, mStepTime);
    > mFadeState = isBlackE;
    > }
    > }catch(...){ // fading is cosmetic. ignore errors.
    > }
    > #endif
    > }
    > }
    >
    >
    > // ---------------------------------------------------------------------------
    > // € BlackToDesktop -
    > // ---------------------------------------------------------------------------
    > /// If we are in the black state, go to the desktop state. This also restores
    > /// the original gamma of the monitor, over and above what we stored in GetGamma().
    > /// see comment above class declaration.
    > void CFader::BlackToDesktop() throw(){
    > if(UEnvironment::IsRunningOSX()){
    > #if PP_Target_Carbon
    > try{
    > if(isBlackE == mFadeState){
    > FromBlack(mDisplayID, mOriginal, mStepTime);
    > CG::DisplayRestoreColorSyncSettings();
    > mFadeState = isDesktopE;
    > }
    > }catch(...){ // fading is cosmetic. ignore errors.
    > }
    > #endif
    > }
    > }[/ref]
    Gabriel Guest

  5. #5

    Default Re: Image transition effects

    In article <edu>,
    Gabriel Handford <edu> wrote:
     

    As I should have said in my posting, if you want to fade ALL the
    displays, just use

    This file is in the ApplicationServices/CoreGraphics framework:

    #include <CGDisplayFade.h> // read this .h file for examples



    CGDisplayFade(...)
    David Guest

Similar Threads

  1. Image transition question
    By George in forum Macromedia Flash
    Replies: 2
    Last Post: October 6th, 01:44 AM
  2. Image magick effects
    By ravenblue in forum Macromedia Director Basics
    Replies: 2
    Last Post: August 6th, 06:19 AM
  3. Image Effects Question
    By A Scott in forum Macromedia Fireworks
    Replies: 0
    Last Post: September 2nd, 09:59 PM
  4. Vertical Cross-fade Image Transition?
    By Oli11 webforumsuser@macromedia.com in forum Adobe Flash, Flex & Director
    Replies: 0
    Last Post: September 2nd, 08:38 PM

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139