2017-04-17 06:17:10 -06:00

324 lines
12 KiB
C++
Executable File

/**********************************************************************
*<
FILE: toneop.h
DESCRIPTION: Definitions for tone operator. Tone operators are used
to map high dynamic range images into RGB. Usually they
are used with physical energy values.
CREATED BY: Cleve Ard
HISTORY:
*> Copyright (c) 2000, All Rights Reserved.
**********************************************************************/
#ifndef __TONEOP_H__
#define __TONEOP_H__
#include <imtl.h>
#include <render.h>
// The tone operator uses the standard Special Effects
// parameter dialog class for its UI.
typedef SFXParamDlg ToneOpParamDlg;
/*=====================================================================
* Tone Operator Interface class
*===================================================================*/
class ToneOperator : public SpecialFX {
public:
ToneOperator() { ClearAFlag(A_TONEOP_PROCESS_BG); }
// Standard methods from ReferenceMaker and Animatable
RefResult NotifyRefChanged(Interval changeInt, RefTargetHandle hTarget,
PartID& partID, RefMessage message) {return REF_SUCCEED;}
SClass_ID SuperClassID() { return TONE_OPERATOR_CLASS_ID; }
// Saves and loads name. These should be called at the start of
// a plug-in's save and load methods.
IOResult Save(ISave *isave) { return SpecialFX::Save(isave); }
IOResult Load(ILoad *iload) { return SpecialFX::Load(iload); }
virtual void SetActive(
bool active,
TimeValue t
) {
if (active ^ (TestAFlag(A_TONEOP_DISABLED) == 0)) {
if (active) {
ClearAFlag(A_TONEOP_DISABLED);
}
else {
SetAFlag(A_TONEOP_DISABLED);
}
NotifyDependents(FOREVER, PART_ALL, REFMSG_CHANGE);
}
}
bool GetProcessBackground() { return TestAFlag(A_TONEOP_PROCESS_BG) != 0; }
void SetProcessBackground(bool active) {
if (active ^ (TestAFlag(A_TONEOP_PROCESS_BG) != 0)) {
if (active) {
SetAFlag(A_TONEOP_PROCESS_BG);
}
else {
ClearAFlag(A_TONEOP_PROCESS_BG);
}
NotifyDependents(FOREVER, PART_ALL, REFMSG_CHANGE);
}
}
bool GetIndirectOnly() { return TestAFlag(A_TONEOP_INDIRECT_ONLY) != 0; }
void SetIndirectOnly(bool active) {
if (active ^ (TestAFlag(A_TONEOP_INDIRECT_ONLY) != 0)) {
if (active) {
SetAFlag(A_TONEOP_INDIRECT_ONLY);
}
else {
ClearAFlag(A_TONEOP_INDIRECT_ONLY);
}
NotifyDependents(FOREVER, PART_ALL, REFMSG_CHANGE);
}
}
// UI Access
// Put up a modal dialog that lets the user edit the plug-ins parameters.
virtual ToneOpParamDlg *CreateParamDialog(IRendParams *ip) { return NULL; }
// Implement this if you are using the ParamMap2 AUTO_UI system and the
// atmosphere has secondary dialogs that don't have the effect as their 'thing'.
// Called once for each secondary dialog for you to install the correct thing.
// Return TRUE if you process the dialog, false otherwise.
virtual BOOL SetDlgThing(ToneOpParamDlg* dlg) { return FALSE; }
// Render access
// Does this tone operator really map physical values to RGB. This method
// is provided so shaders can determine whether the shading calculations
// are in physical or RGB space.
virtual bool IsPhysicalSpace() const { return true; }
// This method is called once per frame when the renderer begins. This
// gives the atmospheric or rendering effect the chance to cache any
// values it uses internally so they don't have to be computed on
// every pixel. But, this method should not be used to perform any very
// long tasks, such as sampling the environment to calculate a
// mapping histogram. This would be the likely method that caches the
// frames physical scaling value.
virtual void Update(TimeValue t, Interval& valid) { }
// This method is called for the operator to do any work it needs
// to do prior to rendering. Rendering using the RenderMapsContext
// uses the identity tone operator.
virtual bool BuildMaps(TimeValue t, RenderMapsContext& rmc)
{ return true; }
// This method is called during subrenders to give the tone operator
// a chance to sample the image with full dynamic range. If your operator
// needs to sample the image, you can set a flag so you know when you are
// sampling.
virtual void SubRenderSample(float energy[3]) { }
// Map an scaled energy value into RGB. The first version of the
// method converts a color value and the second converts a monochrome
// value. The converted color value is stored in <i>energy</i>.
// The converted monochrome value is returned.
// This method assumes that Update has been called to cache the
// various values needed by the tone operator.
// By using a float array to pass in color values, we can use the same
// routine to handle the various classes used to store color information,
// for example, Color, AColor and Point3. The red, green and blue
// components are stored in that order in the array.
virtual void ScaledToRGB(float energy[3]) = 0;
virtual float ScaledToRGB(float energy) = 0;
// Get and Set the Physical value that is scaled to 1.
virtual float GetPhysicalUnit(
TimeValue t,
Interval& valid = Interval(0,0)
) const = 0;
virtual void SetPhysicalUnit(
float value,
TimeValue t
) = 0;
// Scale physical values so they can be used in the renderer. The
// first version of the method converts a color value and the second
// converts a monochrome value. The converted color value is stored
// in <i>energy</i>. The converted monochrome value is returned.
// This method assumes that Update has been called to cache the
// various values needed by the tone operator.
// By using a float array to pass in color values, we can use the same
// routine to handle the various classes used to store color information,
// for example, Color, AColor and Point3. The red, green and blue
// components are stored in that order in the array.
virtual void ScalePhysical(float energy[3]) const = 0;
virtual float ScalePhysical(float energy) const = 0;
// Scale RGB values, just supplied to invert ScalePhysical. The first
// version of the method converts a color value and the second
// converts a monochrome value. The converted color value is stored
// in <i>energy</i>. The converted monochrome value is returned.
// This method assumes that Update has been called to cache the
// various values needed by the tone operator.
// By using a float array to pass in color values, we can use the same
// routine to handle the various classes used to store color information,
// for example, Color, AColor and Point3. The red, green and blue
// components are stored in that order in the array.
virtual void ScaleRGB(float color[3]) const = 0;
virtual float ScaleRGB(float color) const = 0;
// Is this tone operator invertable
bool CanInvert();
// Calculate the physical value from the display value
void RGBToScaled(float energy[3]);
float RGBToScaled(float energy);
};
/*=====================================================================
* Invertable Tone Operator Interface class
*===================================================================*/
// Not all tone operators can map display RGB values to physical values.
// This interface is used by tone operators that are invertable to
// do this mapping.
#define INVERTABLE_TONE_OPERATOR_INTERFACE Interface_ID(0xbe9171b, 0x71183b19)
class ToneOperatorInvertable : public BaseInterface {
public:
// Calculate the physical value from the display value
virtual void InverseMap(float rgb[3]) = 0;
virtual float InverseMap(float rgb) = 0;
};
// Is this tone operator invertable
inline bool ToneOperator::CanInvert()
{
return GetInterface(INVERTABLE_TONE_OPERATOR_INTERFACE) != NULL;
}
// Calculate the physical value from the display value
inline void ToneOperator::RGBToScaled(float energy[3])
{
ToneOperatorInvertable* p = static_cast<ToneOperatorInvertable*>(
GetInterface(INVERTABLE_TONE_OPERATOR_INTERFACE));
if (p != NULL)
p->InverseMap(energy);
}
inline float ToneOperator::RGBToScaled(float energy)
{
ToneOperatorInvertable* p = static_cast<ToneOperatorInvertable*>(
GetInterface(INVERTABLE_TONE_OPERATOR_INTERFACE));
return p == NULL ? energy : p->InverseMap(energy);
}
// Does this tone operator really map physical values to RGB. This method
// is provided so shaders can determine whether the shading calculations
// are in physical or RGB space.
inline bool ShadeContext::IsPhysicalSpace() const
{ return globContext != NULL && globContext->pToneOp != NULL
&& globContext->pToneOp->IsPhysicalSpace( ); }
// Map an scaled energy value into RGB. The first version of the
// method converts a color value and the second converts a monochrome
// value. The converted color value is stored in <i>energy</i>.
// The converted monochrome value is returned.
inline float ShadeContext::ScaledToRGB( float energy ) const
{ return globContext != NULL && globContext->pToneOp != NULL
? energy : globContext->pToneOp->ScaledToRGB( energy ); }
// Map an energy value int out.c into RGB. The converted value is stored in
// out.c.
inline void ShadeContext::ScaledToRGB( )
{ ScaledToRGB( out.c ); }
// Scale physical values so they can be used in the renderer. The
// first version of the method converts a color value and the second
// converts a monochrome value. The converted color value is stored
// in <i>energy</i>. The converted monochrome value is returned.
inline float ShadeContext::ScalePhysical(float energy) const
{ return globContext != NULL && globContext->pToneOp != NULL
? energy : globContext->pToneOp->ScalePhysical( energy ); }
// Scale RGB values, just supplied to invert ScalePhysical. The first
// version of the method converts a color value and the second
// converts a monochrome value. The converted color value is stored
// in <i>energy</i>. The converted monochrome value is returned.
inline float ShadeContext::ScaleRGB(float energy) const
{ return globContext != NULL && globContext->pToneOp != NULL
? energy : globContext->pToneOp->ScaleRGB( energy ); }
/*=====================================================================
* Tone Operator Core Interface class
*===================================================================*/
// This class is used to get access to the tone operator and
// its UI.
#define TONE_OPERATOR_INTERFACE Interface_ID(0x1563269c, 0x7ec41d84)
class ToneOperatorInterface : public FPStaticInterface {
public:
typedef void (*ToneChangeCallback)(
ToneOperator* newOp,
ToneOperator* oldOp,
void* param
);
// Get and Set the tone operator in the scene
virtual ToneOperator* GetToneOperator() const = 0;
virtual void SetToneOperator(ToneOperator* op) = 0;
virtual void RegisterToneOperatorChangeNotification(
ToneChangeCallback callback,
void* param
) = 0;
virtual void UnRegisterToneOperatorChangeNotification(
ToneChangeCallback callback,
void* param
) = 0;
};
/*=====================================================================
* class IToneOperatorExtension
*
* This class is an extension to allow tone operators to work more
* closely with radiosity engines. The interface supports tone operator
* that can choose to display illuminance (irradiance) or luminance
* (radiance). This is especially useful for performing lighting analysis
* through special-purpose tone operators.
*===================================================================*/
#define ITONEOPERATOR_EXTENSION_INTERFACE Interface_ID(0x512b3541, 0x1c413aad)
class IToneOperatorExtension : public BaseInterface {
public:
enum Quantity {
kQuantity_Illuminance = 0,
kQuantity_Luminance = 1
};
virtual Quantity GetUsedQuantity() const = 0;
virtual void SetUsedQuantity(Quantity q) = 0;
// -- from BaseInterface
virtual Interface_ID GetID() { return ITONEOPERATOR_EXTENSION_INTERFACE; }
};
#endif