toneop.h

Go to the documentation of this file.
00001 /**********************************************************************
00002  *<
00003     FILE: toneop.h
00004 
00005     DESCRIPTION: Definitions for tone operator. Tone operators are used
00006                  to map high dynamic range images into RGB. Usually they
00007                  are used with physical energy values.
00008 
00009     CREATED BY: Cleve Ard
00010 
00011     HISTORY:
00012 
00013  *> Copyright (c) 2000, All Rights Reserved.
00014  **********************************************************************/
00015 
00016 
00017 #pragma once
00018 
00019 #include "imtl.h"
00020 #include "render.h"
00021 
00022 // The tone operator uses the standard Special Effects
00023 // parameter dialog class for its UI.
00024 typedef SFXParamDlg ToneOpParamDlg;
00025 
00026 /*=====================================================================
00027  * Tone Operator Interface class
00028  *===================================================================*/
00029 
00066 #pragma warning(push)
00067 #pragma warning(disable:4239)
00068 
00069 class ToneOperator : public SpecialFX {
00070 public:
00071 
00072     ToneOperator() { ClearAFlag(A_TONEOP_PROCESS_BG); }
00073 
00074     // Standard methods from ReferenceMaker and Animatable
00075     #pragma warning(push)
00076     #pragma warning(disable:4100)
00077     RefResult NotifyRefChanged(Interval changeInt, RefTargetHandle hTarget, 
00078         PartID& partID,  RefMessage message) {return REF_SUCCEED;}
00079     SClass_ID SuperClassID() { return TONE_OPERATOR_CLASS_ID; }
00080     
00081     // Saves and loads name. These should be called at the start of
00082     // a plug-in's save and load methods.
00083     IOResult Save(ISave *isave) { return SpecialFX::Save(isave); }
00084     IOResult Load(ILoad *iload) { return SpecialFX::Load(iload); }
00085 
00086     virtual BOOL Active(TimeValue t) { return !TestAFlag(A_TONEOP_DISABLED); }
00108     virtual void SetActive(
00109         bool        active,
00110         TimeValue   t
00111     ) {
00112         if (active ^ (TestAFlag(A_TONEOP_DISABLED) == 0)) {
00113             if (active) {
00114                 ClearAFlag(A_TONEOP_DISABLED);
00115             }
00116             else {
00117                 SetAFlag(A_TONEOP_DISABLED);
00118             }
00119             NotifyDependents(FOREVER, (PartID)PART_ALL, REFMSG_CHANGE);
00120         }
00121     }
00122 
00125     bool GetProcessBackground() { return TestAFlag(A_TONEOP_PROCESS_BG) != 0; }
00130     void SetProcessBackground(bool active) {
00131         if (active ^ (TestAFlag(A_TONEOP_PROCESS_BG) != 0)) {
00132             if (active) {
00133                 SetAFlag(A_TONEOP_PROCESS_BG);
00134             }
00135             else {
00136                 ClearAFlag(A_TONEOP_PROCESS_BG);
00137             }
00138             NotifyDependents(FOREVER, (PartID)PART_ALL, REFMSG_CHANGE);
00139         }
00140     }
00141 
00142     bool GetIndirectOnly() { return TestAFlag(A_TONEOP_INDIRECT_ONLY) != 0; }
00143     void SetIndirectOnly(bool active) {
00144         if (active ^ (TestAFlag(A_TONEOP_INDIRECT_ONLY) != 0)) {
00145             if (active) {
00146                 SetAFlag(A_TONEOP_INDIRECT_ONLY);
00147             }
00148             else {
00149                 ClearAFlag(A_TONEOP_INDIRECT_ONLY);
00150             }
00151             NotifyDependents(FOREVER, (PartID)PART_ALL, REFMSG_CHANGE);
00152         }
00153     }
00154 
00155     // UI Access
00156 
00157     // Put up a modal dialog that lets the user edit the plug-ins parameters.
00172     virtual ToneOpParamDlg *CreateParamDialog(IRendParams *ip) { return NULL; }
00173 
00174     // Implement this if you are using the ParamMap2 AUTO_UI system and the 
00175     // atmosphere has secondary dialogs that don't have the effect as their 'thing'.
00176     // Called once for each secondary dialog for you to install the correct thing.
00177     // Return TRUE if you process the dialog, false otherwise.
00186     virtual BOOL SetDlgThing(ToneOpParamDlg* dlg) { return FALSE; }
00187 
00188     // Render access
00189 
00190     // Does this tone operator really map physical values to RGB. This method
00191     // is provided so shaders can determine whether the shading calculations
00192     // are in physical or RGB space.
00198     virtual bool IsPhysicalSpace() const { return true; }
00199 
00200     // This method is called once per frame when the renderer begins. This
00201     // gives the atmospheric or rendering effect the chance to cache any
00202     // values it uses internally so they don't have to be computed on
00203     // every pixel. But, this method should not be used to perform any very
00204     // long tasks, such as sampling the environment to calculate a
00205     // mapping histogram. This would be the likely method that caches the
00206     // frames physical scaling value.
00219     virtual void Update(TimeValue t, Interval& valid) { }
00220 
00221     // This method is called for the operator to do any work it needs
00222     // to do prior to rendering. Rendering using the RenderMapsContext
00223     // uses the identity tone operator.
00239     virtual bool BuildMaps(TimeValue t, RenderMapsContext& rmc)
00240         { return true; }
00241 
00242     // This method is called during subrenders to give the tone operator
00243     // a chance to sample the image with full dynamic range. If your operator
00244     // needs to sample the image, you can set a flag so you know when you are
00245     // sampling.
00246     virtual void SubRenderSample(float energy[3]) { }
00247     #pragma warning(pop)
00248     // Map an scaled energy value into RGB. The first version of the
00249     // method converts a color value and the second converts a monochrome
00250     // value. The converted color value is stored in <i>energy</i>.
00251     // The converted monochrome value is returned.
00252     // This method assumes that Update has been called to cache the
00253     // various values needed by the tone operator.
00254     // By using a float array to pass in color values, we can use the same
00255     // routine to handle the various classes used to store color information,
00256     // for example, Color, AColor and Point3. The red, green and blue
00257     // components are stored in that order in the array.
00273     virtual void ScaledToRGB(float energy[3]) = 0;
00281     virtual float ScaledToRGB(float energy) = 0;
00282 
00283     // Get and Set the Physical value that is scaled to 1.
00290     virtual float GetPhysicalUnit(
00291         TimeValue   t,
00292         Interval&   valid = Interval(0,0)
00293     ) const = 0;
00302     virtual void SetPhysicalUnit(
00303         float       value,
00304         TimeValue   t
00305     ) = 0;
00306 
00307     // Scale physical values so they can be used in the renderer. The
00308     // first version of the method converts a color value and the second
00309     // converts a monochrome value. The converted color value is stored
00310     // in <i>energy</i>. The converted monochrome value is returned.
00311     // This method assumes that Update has been called to cache the
00312     // various values needed by the tone operator.
00313     // By using a float array to pass in color values, we can use the same
00314     // routine to handle the various classes used to store color information,
00315     // for example, Color, AColor and Point3. The red, green and blue
00316     // components are stored in that order in the array.
00328     virtual void ScalePhysical(float energy[3]) const = 0;
00337     virtual float ScalePhysical(float energy) const = 0;
00338 
00339     // Scale RGB values, just supplied to invert ScalePhysical. The first
00340     // version of the method converts a color value and the second
00341     // converts a monochrome value. The converted color value is stored
00342     // in <i>energy</i>. The converted monochrome value is returned.
00343     // This method assumes that Update has been called to cache the
00344     // various values needed by the tone operator.
00345     // By using a float array to pass in color values, we can use the same
00346     // routine to handle the various classes used to store color information,
00347     // for example, Color, AColor and Point3. The red, green and blue
00348     // components are stored in that order in the array.
00358     virtual void ScaleRGB(float color[3]) const = 0;
00365     virtual float ScaleRGB(float color) const = 0;
00366     
00367     // Is this tone operator invertable
00368     bool CanInvert();
00369     
00370     // Calculate the physical value from the display value
00371     void RGBToScaled(float energy[3]);
00372     float RGBToScaled(float energy);
00373 };
00374 
00375 
00376 #pragma warning(pop)
00377 /*=====================================================================
00378  * Invertable Tone Operator Interface class
00379  *===================================================================*/
00380 // Not all tone operators can map display RGB values to physical values.
00381 // This interface is used by tone operators that are invertable to
00382 // do this mapping.
00383 
00384 #define INVERTABLE_TONE_OPERATOR_INTERFACE  Interface_ID(0xbe9171b, 0x71183b19)
00385 
00386 class ToneOperatorInvertable : public BaseInterface {
00387 public:
00388     // Calculate the physical value from the display value
00389     virtual void InverseMap(float rgb[3]) = 0;
00390     virtual float InverseMap(float rgb) = 0;
00391 };
00392 
00393 
00394 // Is this tone operator invertable
00395 inline bool ToneOperator::CanInvert()
00396 {
00397     return GetInterface(INVERTABLE_TONE_OPERATOR_INTERFACE) != NULL;
00398 }
00399 
00400 // Calculate the physical value from the display value
00401 inline void ToneOperator::RGBToScaled(float energy[3])
00402 {
00403     ToneOperatorInvertable* p = static_cast<ToneOperatorInvertable*>(
00404         GetInterface(INVERTABLE_TONE_OPERATOR_INTERFACE));
00405         
00406     if (p != NULL)
00407         p->InverseMap(energy);
00408 }
00409 
00410 inline float ToneOperator::RGBToScaled(float energy)
00411 {
00412     ToneOperatorInvertable* p = static_cast<ToneOperatorInvertable*>(
00413         GetInterface(INVERTABLE_TONE_OPERATOR_INTERFACE));
00414         
00415     return p == NULL ? energy : p->InverseMap(energy);
00416 }
00417 
00418 // Does this tone operator really map physical values to RGB. This method
00419 // is provided so shaders can determine whether the shading calculations
00420 // are in physical or RGB space.
00421 inline bool ShadeContext::IsPhysicalSpace() const
00422     { return globContext != NULL && globContext->pToneOp != NULL
00423         && globContext->pToneOp->IsPhysicalSpace( ); }
00424 
00425 // Map an scaled energy value into RGB. The first version of the
00426 // method converts a color value and the second converts a monochrome
00427 // value. The converted color value is stored in <i>energy</i>.
00428 // The converted monochrome value is returned.
00429 inline float ShadeContext::ScaledToRGB( float energy ) const
00430     { return (globContext == NULL || globContext->pToneOp == NULL)
00431         ? energy : globContext->pToneOp->ScaledToRGB( energy ); }
00432 
00433 // Map an energy value int out.c into RGB. The converted value is stored in
00434 // out.c.
00435 inline void ShadeContext::ScaledToRGB( )
00436     { ScaledToRGB( out.c ); }
00437 
00438 // Scale physical values so they can be used in the renderer. The
00439 // first version of the method converts a color value and the second
00440 // converts a monochrome value. The converted color value is stored
00441 // in <i>energy</i>. The converted monochrome value is returned.
00442 inline float ShadeContext::ScalePhysical(float energy) const
00443     { return (globContext == NULL || globContext->pToneOp == NULL)
00444         ? energy : globContext->pToneOp->ScalePhysical( energy ); }
00445 
00446 // Scale RGB values, just supplied to invert ScalePhysical. The first
00447 // version of the method converts a color value and the second
00448 // converts a monochrome value. The converted color value is stored
00449 // in <i>energy</i>. The converted monochrome value is returned.
00450 inline float ShadeContext::ScaleRGB(float energy) const
00451     { return (globContext == NULL || globContext->pToneOp == NULL)
00452         ? energy : globContext->pToneOp->ScaleRGB( energy ); }
00453 
00454 
00455 /*=====================================================================
00456  * Tone Operator Core Interface class
00457  *===================================================================*/
00458 
00459 // This class is used to get access to the tone operator and
00460 // its UI.
00461 #define TONE_OPERATOR_INTERFACE Interface_ID(0x1563269c, 0x7ec41d84)
00462 
00474 class ToneOperatorInterface : public FPStaticInterface {
00475 public:
00476     typedef void (*ToneChangeCallback)(
00477         ToneOperator*  newOp,
00478         ToneOperator*  oldOp,
00479         void*          param
00480     );
00481 
00482     // Get and Set the tone operator in the scene
00485     virtual ToneOperator* GetToneOperator() const = 0;
00489     virtual void SetToneOperator(ToneOperator* op) = 0;
00490 
00501     virtual void RegisterToneOperatorChangeNotification(
00502         ToneChangeCallback   callback,
00503         void*                param
00504     ) = 0;
00516     virtual void UnRegisterToneOperatorChangeNotification(
00517         ToneChangeCallback   callback,
00518         void*                param
00519     ) = 0;
00520 };
00521 
00522 
00523 /*=====================================================================
00524  * class IToneOperatorExtension
00525  *
00526  * This class is an extension to allow tone operators to work more
00527  * closely with radiosity engines. The interface supports tone operator
00528  * that can choose to display illuminance (irradiance) or luminance
00529  * (radiance). This is especially useful for performing lighting analysis
00530  * through special-purpose tone operators.
00531  *===================================================================*/
00532 #define ITONEOPERATOR_EXTENSION_INTERFACE Interface_ID(0x512b3541, 0x1c413aad)
00533 
00534 class IToneOperatorExtension : public BaseInterface {
00535 
00536 public:
00537 
00538     enum Quantity {
00539         kQuantity_Illuminance = 0,
00540         kQuantity_Luminance = 1
00541     };
00542 
00543     virtual Quantity GetUsedQuantity() const = 0;
00544     virtual void SetUsedQuantity(Quantity q) = 0;
00545 
00546     // -- from BaseInterface
00547     virtual Interface_ID GetID() { return ITONEOPERATOR_EXTENSION_INTERFACE; }
00548     
00549 };
00550 
00551