// -*- C++ -*-
#ifndef RIRENDERER_H
#define RIRENDERER_H
/* Copyright 1996 
 * Mon Aug 11 19:34:27 1997  Brian Smits  (bes@phoenix.cs.utah.edu)
 * 
 * RiRenderer.H
 * 
 *	
 * 
 * $Id: RiRenderer.H,v 1.6 1999/10/01 18:26:31 bes Exp $ 
 * 
 */
#ifndef RICOMMON_H
#include <RiCommon.H>
#endif

class RiRayShader;

#ifndef RISPECTRUM_H
#include <RiSpectrum.H>
#endif

#ifndef RICAMERA_H
#include <RiCamera.H>
#endif

#ifndef RISAMPLEPATTERN_H
#include <RiSamplePattern.H>
#endif

#ifndef RIRAYOBJECT_H
#include <RiRayObject.H>
#endif

#ifndef RIBACKGROUND_H
#include <RiBackground.H>
#endif

#ifndef RIIMAGE_H
#include <RiImage.H>
#endif


/***************************************************************
CLASS
    RiRenderer
    Basic renderer interface.

DESCRIPTION
    Basic renderer interface, user calls Render, which in turn calls the
    protected members Initialize, DoRender, and Cleanup, which can be overridden
    in derived classes

PATTERNS
    Template Method
    
****************************************************************/

class RiRenderer {
  public:
				//// Destructor for RiRenderer
    ~RiRenderer() {}
				//// Calls Initialize, DoRender, and Cleanup in sequence
    void Render();
  protected:
				//// Does nothing, default implementation
    virtual void Initialize();
				//// Renders the scene
    virtual void DoRender() = 0;
				//// Does nothing, default implementation
    virtual void Cleanup();
};


/***************************************************************
CLASS
    RiRayCameraPixelRenderer
    This is a general ray tracing engine. 

DESCRIPTION
    This provides a general ray tracing engine.  It provides everything
    except for the shader.  To use, override the GetRayShader() method

****************************************************************/

class RiRayCameraPixelRenderer : public RiRenderer {
  public:
    RiRayCameraPixelRenderer();
				//// Set the camera
    void		SetRayCamera(RiRayCamera *camera);
				//// Set the camera
    void		SetImage(RiImage *image);
				//// Set the sampling pattern for each pixel
    void		SetSamplingPattern(const RiSamplePattern &pattern);
				//// Return the shader to be used for shading the pixel
    virtual RiRayShader *GetRayShader() = 0;
				//// Get the environment
    RiRayObject		*GetEnvironment();
				//// Set the environment
    void		 SetEnvironment(RiRayObject *obj);
				////
    RiBackground        *GetBackground();
				//// Set the background
    void		 SetBackground(RiBackground *bg);

  protected:
				//// Renders the scene
    virtual void 	DoRender();
				//// A mapping from the [0,1]^2 domain of the samples
				// to a domain centered at 0,0.  The result is scaled by
				// sizeU and sizeV and added to the pixel center
    virtual RiVector2	SquareWarpSample(const RiVector2 &samp);
				//// sample the pixel at centerU,V with size sizeU,V
    virtual RiSpectrum  DoPixel(RiReal centerU, RiReal centerV, RiReal sizeU, RiReal sizeV);
				//// Sampling strategy for the pixel and future bounces
    RiSamplePattern	 samples;
				//// Camera used to generate the rays at each pixel
    RiRayCamera		*camera;
				//// Image to be filled;
    RiImage		*image;
				//// The environment against which rays are traced
    RiRayObject		*env;
				//// The background of the scene
    RiBackground	*background;
};


/***************************************************************
CLASS
    RiScreenRenderer
    This encapsulates a renderer that needs random access to pixels

DESCRIPTION
    The Render() method must fill an image somehow.  It should be able
    to handle traditional scanline rendering, as well as metropolis and
    bi-directional stuff.

****************************************************************/

class RiScreenRenderer : public RiRenderer {
  public:
    // GROUP: Members
				////
    virtual void DoRender() = 0;
				////
    void     SetImage(RiImage *img);
				////
    RiImage &GetImage();
  private:
    RiImage *img;
};

#ifdef UNDEF

/***************************************************************
CLASS
    RiMetroSamplingRenderer
     Not Metropolis, uses technique to generate ray bundles

DESCRIPTION
     <Detailed description with any warnings>

****************************************************************/

class RiMetroSamplingRenderer : public RiScreenRenderer {
  public:
    //// Default Constructor
    RiMetroSamplingRenderer();
				// GROUP: Accessors
				//// Set the camera
    void		SetRayCamera(RiRayCamera *camera);
				//// Set the sampling pattern for each pixel
    void		SetSamplingPattern(const RiSamplePattern &pattern);
				//// Set the background
    void		 SetBackground(RiBackground *bg);
				//// Set the environment
    void		 SetEnvironment(RiRayObject *obj);
				// GROUP: Members
				////
    virtual void DoRender();
  private:
    ////Copy Constructor
    RiMetroSamplingRenderer(const RiMetroSamplingRenderer &);
    //// Assignment
    RiMetroSamplingRenderer &operator=(const RiMetroSamplingRenderer &);

  				//// Sampling strategy for the pixel and future bounces
    RiSamplePattern	 samples;
				//// Camera used to generate the rays at each pixel
    RiRayCamera		*camera;
				//// Iterator used to determine which pixels and in which order
    RiImageIterator	*imageIter;
				//// The environment against which rays are traced
    RiRayObject		*env;
				//// The background of the scene
    RiBackground	*background;  
};
#endif

#endif /* RIRENDERER_H */

