Very optimized in sense of speed / memory usage as it supports several orientations...
authormtadel <mtadel@f7af4fe6-9843-0410-8265-dc069ae4e863>
Tue, 14 Nov 2006 16:27:41 +0000 (16:27 +0000)
committermtadel <mtadel@f7af4fe6-9843-0410-8265-dc069ae4e863>
Tue, 14 Nov 2006 16:27:41 +0000 (16:27 +0000)
EVE/Reve/QuadSet.cxx
EVE/Reve/QuadSet.h
EVE/Reve/QuadSetGL.cxx
EVE/Reve/QuadSetGL.h

index 630c42f..b450d0c 100644 (file)
@@ -1,6 +1,7 @@
 // $Header$
 
 #include "QuadSet.h"
+#include "RGBAPalette.h"
 
 #include <TColor.h>
 
@@ -155,3 +156,440 @@ void OldQuadSet::ComputeBBox()
   // printf("%s BBox is x(%f,%f), y(%f,%f), z(%f,%f)\n", GetName(),
   //        fBBox[0], fBBox[1], fBBox[2], fBBox[3], fBBox[4], fBBox[5]);
 }
+
+/**************************************************************************/
+/**************************************************************************/
+/**************************************************************************/
+/**************************************************************************/
+
+//__________________________________________________________________________
+// QuadSet
+//
+// Supports various internal formats that result in rendering of a
+// set of rectangular objects.
+//
+// Names of internal structures and their variables use fixed
+// assignment to x, z, y coordinates; the render types can override
+// this convention and impose Y as a fixed coordinate.
+// For quad modes the deltas are expected to be positive.
+// For line modes negative deltas are ok.
+
+ClassImp(Reve::QuadSet)
+
+QuadSet::QuadSet(const Text_t* n, const Text_t* t) :
+  RenderElement(),
+  TNamed(n, t),
+
+  fQuadType(QT_Undef),
+  fValueIsColor(kFALSE),
+  fDefaultValue(kMinInt),
+  fPlex(),
+  fLastQuad(0),
+
+  fDefWidth(1), fDefHeight(1), fDefCoord(0),
+
+  fFrame  (0),
+  fPalette(0)
+{}
+
+QuadSet::QuadSet(QuadType_e quadType, Bool_t valIsCol, Int_t chunkSize,
+                const Text_t* n, const Text_t* t) :
+  RenderElement(),
+  TNamed(n, t),
+
+  fQuadType(quadType),
+  fValueIsColor(valIsCol),
+  fDefaultValue(valIsCol ? 0 : kMinInt),
+  fPlex(SizeofAtom(quadType), chunkSize),
+  fLastQuad(0),
+
+  fDefWidth(1), fDefHeight(1), fDefCoord(0),
+
+  fFrame  (0),
+  fPalette(0)
+{}
+
+QuadSet::~QuadSet()
+{
+  SetFrame(0);
+  SetPalette(0);
+}
+
+/**************************************************************************/
+
+Int_t QuadSet::SizeofAtom(QuadSet::QuadType_e qt)
+{
+  switch (qt) {
+    case QT_Undef:                return 0;
+    case QT_FreeQuad:             return sizeof(FreeQuad);
+    case QT_AxisAligned:          return sizeof(AAQuad);
+    case QT_AxisAlignedFixedDim:  return sizeof(AAFixDimQuad);
+    case QT_AxisAlignedFixedY:
+    case QT_AxisAlignedFixedZ:    return sizeof(AAFixZQuad);
+    case QT_AxisAlignedFixedDimY:
+    case QT_AxisAlignedFixedDimZ: return sizeof(AAFixDimZQuad);
+    case QT_LineFixedY:
+    case QT_LineFixedZ:           return sizeof(LineFixedZ);
+  }
+  return 0;
+}
+
+/**************************************************************************/
+
+void QuadSet::Reset(QuadSet::QuadType_e quadType, Bool_t valIsCol, Int_t chunkSize)
+{
+  fQuadType     = quadType;
+  fValueIsColor = valIsCol;
+  fDefaultValue = valIsCol ? 0 : kMinInt;
+  fPlex.Reset(SizeofAtom(fQuadType), chunkSize);
+}
+
+void QuadSet::RefitPlex()
+{
+  // Instruct underlying memory allocator to regroup itself into a
+  // contiguous memory chunk.
+
+  fPlex.Refit();
+}
+
+/**************************************************************************/
+
+void QuadSet::ScanMinMaxValues(Int_t& min, Int_t& max)
+{
+  if (fValueIsColor || fPlex.Size() == 0) return;
+  min = kMaxInt;
+  max = kMinInt;
+  for (Int_t c=0; c<fPlex.VecSize(); ++c)
+  {
+    Char_t* a = fPlex.Chunk(c);
+    Int_t   n = fPlex.NAtoms(c);
+    while (n--)
+    {
+      Int_t v = ((QuadBase*)a)->fValue;
+      if (v < min) min = v;
+      if (v > max) max = v;
+      a += fPlex.S();
+    }
+  }
+  if (min == max)
+    --min;
+}
+
+/**************************************************************************/
+
+void QuadSet::SetFrame(FrameBox* b)
+{
+  if (fFrame == b) return;
+  if (fFrame) fFrame->DecRefCount();
+  fFrame = b;
+  if (fFrame) {
+    fFrame->IncRefCount();
+    SetMainColorPtr(fFrame->PtrFrameColor());
+  } else {
+    SetMainColorPtr(0);
+  }
+}
+
+void QuadSet::SetPalette(RGBAPalette* p)
+{
+  if (fPalette == p) return;
+  if (fPalette) fPalette->DecRefCount();
+  fPalette = p;
+  if (fPalette) {
+    fPalette->IncRefCount();
+    SetMainColorPtr(fPalette->PtrDefaultColor());
+  } else {
+    SetMainColorPtr(0);
+  }
+}
+
+/**************************************************************************/
+
+QuadSet::QuadBase* QuadSet::NewQuad()
+{
+  fLastQuad = new (fPlex.NewAtom()) QuadBase(fDefaultValue);
+  return fLastQuad;
+}
+
+void QuadSet::AddQuad(Float_t* verts)
+{
+  static const Exc_t eH("QuadSet::AddQuad ");
+  if (fQuadType != QT_FreeQuad)
+    throw(eH + "expect free quad-type.");
+
+  FreeQuad* fq = (FreeQuad*) NewQuad();
+  memcpy(fq->fVertices, verts, sizeof(fq->fVertices));
+}
+
+void QuadSet::AddQuad(Float_t x, Float_t y)
+{
+  AddQuad(x, y, fDefCoord, fDefWidth, fDefHeight);
+}
+
+void QuadSet::AddQuad(Float_t x, Float_t y, Float_t z)
+{
+  AddQuad(x, y, z, fDefWidth, fDefHeight);
+}
+
+void QuadSet::AddQuad(Float_t x, Float_t y, Float_t w, Float_t h)
+{
+  AddQuad(x, y, fDefCoord, w, h);
+}
+
+void QuadSet::AddQuad(Float_t x, Float_t y, Float_t z, Float_t w, Float_t h)
+{
+  static const Exc_t eH("QuadSet::AddAAQuad ");
+
+  AAFixDimZQuad& fq = * (AAFixDimZQuad*) NewQuad();
+  fq.fX = x; fq.fY = y;
+  switch (fQuadType)
+  {
+    case QT_AxisAligned: {
+      AAQuad& q = (AAQuad&) fq;
+      q.fZ = z; q.fW = w; q.fH = h;
+      break;
+    }
+    case QT_AxisAlignedFixedDim: {
+      AAFixDimQuad& q =  (AAFixDimQuad&) fq;
+      q.fZ = z;
+      break;
+    }
+    case QT_AxisAlignedFixedY:
+    case QT_AxisAlignedFixedZ: {
+      AAFixZQuad& q = (AAFixZQuad&) fq;
+      q.fW = w; q.fH = h;
+      break;
+    }
+    case QT_AxisAlignedFixedDimY:
+    case QT_AxisAlignedFixedDimZ: {
+      break;
+    }
+    case QT_LineFixedY:
+    case QT_LineFixedZ: {
+      LineFixedZ& q = (LineFixedZ&) fq;
+      q.fDx = w; q.fDy = h;
+      break;
+    }
+    default:
+      throw(eH + "expect axis-aligned quad-type.");
+  }
+}
+
+/**************************************************************************/
+
+void QuadSet::QuadValue(Int_t value)
+{
+  fLastQuad->fValue = value;
+}
+
+void QuadSet::QuadColor(Color_t ci)
+{
+  ColorFromIdx(ci, (UChar_t*) & fLastQuad->fValue, kTRUE);
+}
+
+void QuadSet::QuadColor(UChar_t r, UChar_t g, UChar_t b, UChar_t a)
+{
+  UChar_t* x = (UChar_t*) & fLastQuad->fValue;
+  x[0] = r; x[1] = g; x[2] = b; x[3] = a;
+}
+
+/**************************************************************************/
+/**************************************************************************/
+
+void QuadSet::ComputeBBox()
+{
+  static const Exc_t eH("QuadSet::ComputeBBox ");
+
+  // !!!! Missing handling of FrameBox !!!!
+  // It shoud even simpify things ...
+
+  if(fPlex.Size() == 0) {
+    BBoxZero();
+    return;
+  }
+
+  BBoxInit();
+  if (fQuadType == QT_AxisAlignedFixedZ    ||
+      fQuadType == QT_AxisAlignedFixedDimZ)
+  {
+    fBBox[4] = fDefCoord;
+    fBBox[5] = fDefCoord;
+  }
+  else if (fQuadType == QT_AxisAlignedFixedY    ||
+          fQuadType == QT_AxisAlignedFixedDimY)
+  {
+    fBBox[2] = fDefCoord;
+    fBBox[3] = fDefCoord;
+  }
+
+  for (Int_t c=0; c<fPlex.VecSize(); ++c)
+  {
+    QuadBase* qbp = (QuadBase*) fPlex.Chunk(c);
+    Int_t       n = fPlex.NAtoms(c);
+
+    switch (fQuadType)
+    {
+
+      case QT_FreeQuad:
+      {
+       FreeQuad* qp = (FreeQuad*) qbp;
+       while (n--) {
+         Float_t* p = qp->fVertices;
+         BBoxCheckPoint(p); p += 3;
+         BBoxCheckPoint(p); p += 3;
+         BBoxCheckPoint(p); p += 3;
+         BBoxCheckPoint(p);
+         ++qp;
+       }
+       break;
+      }
+
+      case QT_AxisAligned:
+      {
+       AAQuad* qp = (AAQuad*) qbp;
+       while (n--) {
+         AAQuad& q = * qp;
+         if(q.fX        < fBBox[0]) fBBox[0] = q.fX;
+         if(q.fX + q.fW > fBBox[1]) fBBox[1] = q.fX + q.fW;
+         if(q.fY        < fBBox[2]) fBBox[2] = q.fY;
+         if(q.fY + q.fH > fBBox[3]) fBBox[3] = q.fY + q.fH;
+         if(q.fZ        < fBBox[4]) fBBox[4] = q.fZ;
+         if(q.fZ        > fBBox[5]) fBBox[5] = q.fZ;
+         ++qp;
+       }
+       break;
+      }
+
+      case QT_AxisAlignedFixedDim:
+      {
+       AAFixDimQuad* qp =  (AAFixDimQuad*) qbp;
+       const Float_t& w = fDefWidth;
+       const Float_t& h = fDefHeight;
+       while (n--) {
+         AAFixDimQuad& q = * qp;
+         if(q.fX     < fBBox[0]) fBBox[0] = q.fX;
+         if(q.fX + w > fBBox[1]) fBBox[1] = q.fX + w;
+         if(q.fY     < fBBox[2]) fBBox[2] = q.fY;
+         if(q.fY + h > fBBox[3]) fBBox[3] = q.fY + h;
+         if(q.fZ     < fBBox[4]) fBBox[4] = q.fZ;
+         if(q.fZ     > fBBox[5]) fBBox[5] = q.fZ;
+         ++qp;
+       }
+       break;
+      }
+
+      case QT_AxisAlignedFixedZ:
+      {
+       AAFixZQuad* qp = (AAFixZQuad*) qbp;
+       while (n--) {
+         AAFixZQuad& q = * qp;
+         if(q.fX        < fBBox[0]) fBBox[0] = q.fX;
+         if(q.fX + q.fW > fBBox[1]) fBBox[1] = q.fX + q.fW;
+         if(q.fY        < fBBox[2]) fBBox[2] = q.fY;
+         if(q.fY + q.fH > fBBox[3]) fBBox[3] = q.fY + q.fH;
+         ++qp;
+       }
+       break;
+      }
+
+      case QT_AxisAlignedFixedY:
+      {
+       AAFixZQuad* qp = (AAFixZQuad*) qbp;
+       while (n--) {
+         AAFixZQuad& q = * qp;
+         if(q.fX        < fBBox[0]) fBBox[0] = q.fX;
+         if(q.fX + q.fW > fBBox[1]) fBBox[1] = q.fX + q.fW;
+         if(q.fY        < fBBox[4]) fBBox[4] = q.fY;
+         if(q.fY + q.fH > fBBox[5]) fBBox[5] = q.fY + q.fH;
+         ++qp;
+       }
+       break;
+      }
+
+      case QT_AxisAlignedFixedDimZ:
+      {
+       AAFixDimZQuad* qp =  (AAFixDimZQuad*) qbp;
+       const Float_t& w = fDefWidth;
+       const Float_t& h = fDefHeight;
+       while (n--) {
+         AAFixDimZQuad& q = * qp;
+         if(q.fX     < fBBox[0]) fBBox[0] = q.fX;
+         if(q.fX + w > fBBox[1]) fBBox[1] = q.fX + w;
+         if(q.fY     < fBBox[2]) fBBox[2] = q.fY;
+         if(q.fY + h > fBBox[3]) fBBox[3] = q.fY + h;
+         ++qp;
+       }
+       break;
+      }
+
+      case QT_AxisAlignedFixedDimY:
+      {
+       AAFixDimZQuad* qp =  (AAFixDimZQuad*) qbp;
+       const Float_t& w = fDefWidth;
+       const Float_t& h = fDefHeight;
+       while (n--) {
+         AAFixDimZQuad& q = * qp;
+         if(q.fX     < fBBox[0]) fBBox[0] = q.fX;
+         if(q.fX + w > fBBox[1]) fBBox[1] = q.fX + w;
+         if(q.fY     < fBBox[4]) fBBox[4] = q.fY;
+         if(q.fY + h > fBBox[5]) fBBox[5] = q.fY + h;
+         ++qp;
+       }
+       break;
+      }
+
+      case QT_LineFixedZ:
+      {
+       LineFixedZ* qp =  (LineFixedZ*) qbp;
+       while (n--) {
+         LineFixedZ& q = * qp;
+         BBoxCheckPoint(q.fX,         q.fY,         fDefCoord);
+         BBoxCheckPoint(q.fX + q.fDx, q.fY + q.fDy, fDefCoord);
+         ++qp;
+       }
+       break;
+      }
+
+      case QT_LineFixedY:
+      {
+       LineFixedZ* qp =  (LineFixedZ*) qbp;
+       while (n--) {
+         LineFixedZ& q = * qp;
+         BBoxCheckPoint(q.fX,         fDefCoord, q.fY);
+         BBoxCheckPoint(q.fX + q.fDx, fDefCoord, q.fY + q.fDy);
+         ++qp;
+       }
+       break;
+      }
+
+      default: {
+       throw(eH + "unsupported quad-type.");
+      }
+
+    } // end switch quad-type
+
+  } // end for chunk
+
+}
+
+/**************************************************************************/
+
+void QuadSet::Paint(Option_t* /*option*/)
+{
+  static const Exc_t eH("QuadSet::Paint ");
+
+  TBuffer3D buff(TBuffer3DTypes::kGeneric);
+
+  // Section kCore
+  buff.fID           = this;
+  buff.fColor        = 1;
+  buff.fTransparency = 0;
+  fHMTrans.SetBuffer3D(buff);
+  buff.SetSectionsValid(TBuffer3D::kCore);
+
+  Int_t reqSections = gPad->GetViewer3D()->AddObject(buff);
+  if (reqSections != TBuffer3D::kNone)
+    Error(eH, "only direct GL rendering supported.");
+}
+
+/**************************************************************************/
index b8e982d..31c614c 100644 (file)
@@ -8,9 +8,12 @@
 #include <TAtt3D.h>
 #include <TAttBBox.h>
 
-#include <Reve/RenderElement.h>
 #include <Reve/Reve.h>
-#include "ZTrans.h"
+#include <Reve/RenderElement.h>
+#include <Reve/FrameBox.h>
+#include <Reve/RGBAPalette.h>
+#include <Reve/Plex.h>
+#include <Reve/ZTrans.h>
 
 #include <vector>
 
@@ -80,72 +83,135 @@ class QuadSet : public RenderElement,
 
 public:
   enum QuadType_e
-    { QT_FreeQuad,
-      QT_AxisAligned,
-      QT_AxisAlignedFixedZ,
-      QT_AxisAlignedFixedDim,
-      QT_AxisAlignedFixedDimZ
-    };
+  { 
+    QT_Undef,
+    QT_FreeQuad,
+    QT_AxisAligned,
+    QT_AxisAlignedFixedDim,
+    QT_AxisAlignedFixedZ,
+    QT_AxisAlignedFixedY,
+    QT_AxisAlignedFixedDimZ,
+    QT_AxisAlignedFixedDimY,
+    // line modes (needed for uniform handling of silicon-strip digits)
+    QT_LineFixedZ,
+    QT_LineFixedY
+  };
+
+  enum RenderMode_e { RM_AsIs, RM_Line, RM_Fill };
 
 protected:
-  struct QuadBase {
-    UChar_t fColor[4];
+  struct QuadBase
+  {
+    Int_t fValue;
+    // Here could have additional integer (like time, second threshold).
+
+    QuadBase(Int_t v=0) : fValue(v) {}
   };
 
-  struct FreeQuad : public QuadBase {
+  struct FreeQuad : public QuadBase
+  {
     Float_t fVertices[12];
   };
 
-  struct AAFixDimZQuad : public QuadBase {
+  struct AAFixDimZQuad : public QuadBase
+  {
     Float_t fX, fY;
   };
 
-  struct AAFixDimQuad : public AAFixDimZQuad {
+  struct AAFixDimQuad : public AAFixDimZQuad
+  {
     Float_t fZ;
   };
 
-  struct AAFixZQuad : public AAFixDimZQuad {
+  struct AAFixZQuad : public AAFixDimZQuad
+  {
     Float_t fW, fH;
   };
 
-  struct AAQuad : public AAFixDimQuad {
+  struct AAQuad : public AAFixDimQuad
+  {
     Float_t fW, fH;
   };
 
+  struct LineFixedZ : public AAFixDimZQuad
+  {
+    Float_t fDx, fDy;
+  };
+
 protected:
   QuadType_e        fQuadType;
-  Int_t             fSizeOf;
-  Int_t             fReserveStep;
-  Int_t             fLastEntry;
-  Int_t             fNumReserved;
-
-  // Missing:
-  // * some actual container
-  // * RGBAPalette
-  // * user specifies a value instead of a color
+  Bool_t            fValueIsColor;
+  Int_t             fDefaultValue;
+  VoidCPlex         fPlex;
+  QuadBase*         fLastQuad;     //!
 
-  Color_t           fDefaultColor;
   Float_t           fDefWidth;
   Float_t           fDefHeight;
-  Float_t           fDefZ;
+  Float_t           fDefCoord;
 
+  FrameBox*         fFrame;
+  RGBAPalette*      fPalette;
+  RenderMode_e      fRenderMode;
   ZTrans            fHMTrans;
 
+  static Int_t SizeofAtom(QuadType_e qt);
+  QuadBase*    NewQuad();
+
 public:
   QuadSet(const Text_t* n="QuadSet", const Text_t* t="");
-  virtual ~QuadSet() {}
+  QuadSet(QuadType_e quadType, Bool_t valIsCol, Int_t chunkSize,
+         const Text_t* n="QuadSet", const Text_t* t="");
+  virtual ~QuadSet();
+
+  virtual Bool_t CanEditMainColor() { return kTRUE; }
+
+  void Reset(QuadType_e quadType, Bool_t valIsCol, Int_t chunkSize);
+  void RefitPlex();
+
+  void ScanMinMaxValues(Int_t& min, Int_t& max);
+
+  Float_t GetDefWidth()  const { return fDefWidth;  }
+  Float_t GetDefHeight() const { return fDefHeight; }
+  Float_t GetDefCoord()  const { return fDefCoord;  }
+
+  void SetDefWidth(Float_t v)  { fDefWidth  = v ; }
+  void SetDefHeight(Float_t v) { fDefHeight = v ; }
+  void SetDefCoord(Float_t v)  { fDefCoord  = v ; }
+
+  // --------------------------------
+
+  FrameBox* GetFrame() const { return fFrame; }
+  void SetFrame(FrameBox* b);
+
+  RGBAPalette* GetPalette() const { return fPalette; }
+  void SetPalette(RGBAPalette* p);
+
+  RenderMode_e  GetRenderMode() const { return fRenderMode; }
+  void SetRenderMode(RenderMode_e rm) { fRenderMode = rm; }
 
   ZTrans& RefHMTrans() { return fHMTrans; }
   void SetTransMatrix(Double_t* carr)        { fHMTrans.SetFrom(carr); }
   void SetTransMatrix(const TGeoMatrix& mat) { fHMTrans.SetFrom(mat);  }
 
-  /*
-  void Test(Int_t nquads);
+  // --------------------------------
+
+  void AddQuad(Float_t* verts);
+  void AddQuad(Float_t x, Float_t y);
+  void AddQuad(Float_t x, Float_t y, Float_t z);
+  void AddQuad(Float_t x, Float_t y, Float_t w, Float_t h);
+  void AddQuad(Float_t x, Float_t y, Float_t z, Float_t w, Float_t h);
+
+  void QuadValue(Int_t value);
+  void QuadColor(Color_t ci);
+  void QuadColor(UChar_t r, UChar_t g, UChar_t b, UChar_t a=255);
+
+  // --------------------------------
+
+  // void Test(Int_t nquads);
 
   virtual void ComputeBBox();
 
-  virtual void Paint(Option_t* option = "");
-  */
+  virtual void Paint(Option_t* option="");
 
   ClassDef(QuadSet, 1);
 };
index ea8cf80..59309b3 100644 (file)
@@ -1,7 +1,7 @@
 // $Header$
 
 #include "QuadSetGL.h"
-#include <Reve/QuadSet.h>
+#include <Reve/FrameBoxGL.h>
 
 #include <TGLDrawFlags.h>
 
@@ -72,3 +72,470 @@ void OldQuadSetGL::DirectDraw(const TGLDrawFlags & ) const
 
   glPopAttrib();
 }
+
+
+/**************************************************************************/
+/**************************************************************************/
+/**************************************************************************/
+/**************************************************************************/
+
+//______________________________________________________________________
+// QuadSetGL
+//
+
+ClassImp(QuadSetGL)
+
+/**************************************************************************/
+
+  QuadSetGL::QuadSetGL() : TGLObject(), fM(0)
+{
+  // fCached = false; // Disable DL.
+}
+
+QuadSetGL::~QuadSetGL()
+{}
+
+/**************************************************************************/
+
+Bool_t QuadSetGL::SetModel(TObject* obj)
+{
+  Bool_t ok = SetModelCheckClass(obj, Reve::QuadSet::Class());
+  fM = ok ? dynamic_cast<Reve::QuadSet*>(obj) : 0;
+  return ok;
+}
+
+void QuadSetGL::SetBBox()
+{
+  SetAxisAlignedBBox(fM->AssertBBox());
+}
+
+/**************************************************************************/
+
+inline Bool_t QuadSetGL::SetupColor(const QuadSet::QuadBase& q) const
+{
+  if (fM->fValueIsColor)
+  {
+    glColor4ubv((UChar_t*) & q.fValue);
+  }
+  else
+  {
+    const RGBAPalette& pal = *fM->fPalette;
+
+    if (q.fValue == fM->fDefaultValue)
+    {
+      glColor4ubv(pal.GetDefaultRGBA());
+    }
+    else if ( pal.WithinVisibleRange(q.fValue) == kFALSE )
+    {
+      return kFALSE;
+    }
+    else
+    {
+      glColor4ubv(pal.ColorFromArray(q.fValue));
+    }
+  }
+  return kTRUE;
+}
+
+/**************************************************************************/
+
+void QuadSetGL::DirectDraw(const TGLDrawFlags & flags) const
+{
+  static const Exc_t eH("QuadSetGL::DirectDraw ");
+
+  // printf("QuadSetGLRenderer::DirectDraw Style %d, LOD %d\n", flags.Style(), flags.LOD());
+
+  QuadSet& mQ = * fM;
+  if (mQ.fPlex.Size() == 0)
+    return;
+  if ( ! mQ.fValueIsColor && mQ.fPalette == 0)
+  {
+    Int_t min, max;
+    mQ.ScanMinMaxValues(min, max);
+    mQ.fPalette = new RGBAPalette(min, max, kTRUE, kFALSE);
+  }
+
+  if (mQ.fFrame != 0)
+    FrameBoxGL::Render(mQ.fFrame);
+
+  glPushAttrib(GL_ENABLE_BIT | GL_POLYGON_BIT);
+  glColorMaterial(GL_FRONT_AND_BACK, GL_DIFFUSE);
+  glEnable(GL_COLOR_MATERIAL);
+  glDisable(GL_CULL_FACE);
+
+  if (mQ.fRenderMode == QuadSet::RM_Fill)
+  {
+    glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
+  }
+  else if (mQ.fRenderMode == QuadSet::RM_Line)
+  {
+    glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
+    glDisable(GL_LIGHTING);
+  }
+
+  if (mQ.fQuadType < QuadSet::QT_LineFixedZ)
+    RenderQuads(flags);
+  else
+    RenderLines(flags);
+
+  glPopAttrib();
+
+}
+
+
+void QuadSetGL::RenderQuads(const TGLDrawFlags &) const
+{
+  static const Exc_t eH("QuadSetGL::RenderQuads ");
+
+  QuadSet& mQ = * fM;
+
+  if (mQ.fRenderMode != QuadSet::RM_Line)
+  {
+
+    if (mQ.fQuadType == QuadSet::QT_FreeQuad)
+      glEnable(GL_NORMALIZE);
+    else
+      glNormal3f(0, 0, 1);
+
+    glBegin(GL_QUADS);
+    for (Int_t c=0; c<mQ.fPlex.VecSize(); ++c)
+    {
+      QuadSet::QuadBase* qbp = (QuadSet::QuadBase*) mQ.fPlex.Chunk(c);
+      Int_t n = mQ.fPlex.NAtoms(c);
+
+      switch (mQ.fQuadType)
+      {
+
+       case QuadSet::QT_FreeQuad:
+       {
+         QuadSet::FreeQuad* qp = (QuadSet::FreeQuad*) qbp;
+         Float_t e1[3], e2[3], normal[3];
+         while (n--) {
+           if (SetupColor(*qp) == kFALSE) continue;
+           Float_t* p = qp->fVertices;
+           e1[0] = p[3] - p[0]; e1[1] = p[4] - p[1]; e1[2] = p[5] - p[2];
+           e2[0] = p[6] - p[0]; e2[1] = p[7] - p[1]; e2[2] = p[8] - p[2];
+           TMath::Cross(e1, e2, normal);
+           glNormal3fv(normal);
+           glVertex3fv(p);
+           glVertex3fv(p + 3);
+           glVertex3fv(p + 6);
+           glVertex3fv(p + 9);
+           ++qp;
+         }
+         break;
+       }
+
+       case QuadSet::QT_AxisAligned:
+       {
+         QuadSet::AAQuad* qp = (QuadSet::AAQuad*) qbp;
+         while (n--) {
+           QuadSet::AAQuad& q = * qp;
+           if (SetupColor(q) == kFALSE) continue;
+           glVertex3f(q.fX,        q.fY,        q.fZ);
+           glVertex3f(q.fX + q.fW, q.fY,        q.fZ);
+           glVertex3f(q.fX + q.fW, q.fY + q.fH, q.fZ);
+           glVertex3f(q.fX,        q.fY + q.fH, q.fZ);
+           ++qp;
+         }
+         break;
+       }
+
+       case QuadSet::QT_AxisAlignedFixedDim:
+       {
+         QuadSet::AAFixDimQuad* qp = (QuadSet::AAFixDimQuad*) qbp;
+         const Float_t& w = mQ.fDefWidth;
+         const Float_t& h = mQ.fDefHeight;
+         while (n--) {
+           QuadSet::AAFixDimQuad& q = * qp;
+           if (SetupColor(q) == kFALSE) continue;
+           glVertex3f(q.fX,     q.fY,     q.fZ);
+           glVertex3f(q.fX + w, q.fY,     q.fZ);
+           glVertex3f(q.fX + w, q.fY + h, q.fZ);
+           glVertex3f(q.fX,     q.fY + h, q.fZ);
+           ++qp;
+         }
+         break;
+       }
+
+       case QuadSet::QT_AxisAlignedFixedZ:
+       {
+         QuadSet::AAFixZQuad* qp = (QuadSet::AAFixZQuad*) qbp;
+         const Float_t& z = mQ.fDefCoord;
+         while (n--) {
+           QuadSet::AAFixZQuad& q = * qp;
+           if (SetupColor(q) == kFALSE) continue;
+           glVertex3f(q.fX,        q.fY,        z);
+           glVertex3f(q.fX + q.fW, q.fY,        z);
+           glVertex3f(q.fX + q.fW, q.fY + q.fH, z);
+           glVertex3f(q.fX,        q.fY + q.fH, z);
+           ++qp;
+         }
+         break;
+       }
+
+       case QuadSet::QT_AxisAlignedFixedY:
+       {
+         QuadSet::AAFixZQuad* qp = (QuadSet::AAFixZQuad*) qbp;
+         const Float_t& z = mQ.fDefCoord;
+         while (n--) {
+           QuadSet::AAFixZQuad& q = * qp;
+           if (SetupColor(q) == kFALSE) continue;
+           glVertex3f(q.fX,        z, q.fY);
+           glVertex3f(q.fX + q.fW, z, q.fY);
+           glVertex3f(q.fX + q.fW, z, q.fY + q.fH);
+           glVertex3f(q.fX,        z, q.fY + q.fH);
+           ++qp;
+         }
+         break;
+       }
+
+       case QuadSet::QT_AxisAlignedFixedDimZ:
+       {
+         QuadSet::AAFixDimZQuad* qp = (QuadSet::AAFixDimZQuad*) qbp;
+         const Float_t& z = mQ.fDefCoord;
+         const Float_t& w = mQ.fDefWidth;
+         const Float_t& h = mQ.fDefHeight;
+         while (n--) {
+           QuadSet::AAFixDimZQuad& q = * qp;
+           if (SetupColor(q) == kFALSE) continue;
+           glVertex3f(q.fX,     q.fY,     z);
+           glVertex3f(q.fX + w, q.fY,     z);
+           glVertex3f(q.fX + w, q.fY + h, z);
+           glVertex3f(q.fX,     q.fY + h, z);
+           ++qp;
+         }
+         break;
+       }
+
+       case QuadSet::QT_AxisAlignedFixedDimY:
+       {
+         QuadSet::AAFixDimZQuad* qp = (QuadSet::AAFixDimZQuad*) qbp;
+         const Float_t& z = mQ.fDefCoord;
+         const Float_t& w = mQ.fDefWidth;
+         const Float_t& h = mQ.fDefHeight;
+         while (n--) {
+           QuadSet::AAFixDimZQuad& q = * qp;
+           if (SetupColor(q) == kFALSE) continue;
+           glVertex3f(q.fX,     z, q.fY);
+           glVertex3f(q.fX + w, z, q.fY);
+           glVertex3f(q.fX + w, z, q.fY + h);
+           glVertex3f(q.fX,     z, q.fY + h);
+           ++qp;
+         }
+         break;
+       }
+
+       default:
+         throw(eH + "unsupported quad-type.");
+
+      } // end switch quad-type
+
+    } // end for chunk
+    glEnd();
+
+  }
+  else
+  {
+
+    for (Int_t c=0; c<mQ.fPlex.VecSize(); ++c)
+    {
+      QuadSet::QuadBase* qbp = (QuadSet::QuadBase*) mQ.fPlex.Chunk(c);
+      Int_t n = mQ.fPlex.NAtoms(c);
+
+      switch (mQ.fQuadType)
+      {
+
+       case QuadSet::QT_FreeQuad:
+       {
+         QuadSet::FreeQuad* qp = (QuadSet::FreeQuad*) qbp;
+         while (n--) {
+           if (SetupColor(*qp) == kFALSE) continue;
+           SetupColor(*qp);
+           Float_t* p = qp->fVertices;
+           glBegin(GL_LINE_LOOP);
+           glVertex3fv(p);
+           glVertex3fv(p + 3);
+           glVertex3fv(p + 6);
+           glVertex3fv(p + 9);
+           glEnd();
+           ++qp;
+         }
+         break;
+       }
+
+       case QuadSet::QT_AxisAligned:
+       {
+         QuadSet::AAQuad* qp = (QuadSet::AAQuad*) qbp;
+         while (n--) {
+           QuadSet::AAQuad& q = * qp;
+           if (SetupColor(q) == kFALSE) continue;
+           glBegin(GL_LINE_LOOP);
+           glVertex3f(q.fX,        q.fY,        q.fZ);
+           glVertex3f(q.fX + q.fW, q.fY,        q.fZ);
+           glVertex3f(q.fX + q.fW, q.fY + q.fH, q.fZ);
+           glVertex3f(q.fX,        q.fY + q.fH, q.fZ);
+           glEnd();
+           ++qp;
+         }
+         break;
+       }
+
+       case QuadSet::QT_AxisAlignedFixedDim:
+       {
+         QuadSet::AAFixDimQuad* qp = (QuadSet::AAFixDimQuad*) qbp;
+         const Float_t& w = mQ.fDefWidth;
+         const Float_t& h = mQ.fDefHeight;
+         while (n--) {
+           QuadSet::AAFixDimQuad& q = * qp;
+           if (SetupColor(q) == kFALSE) continue;
+           glBegin(GL_LINE_LOOP);
+           glVertex3f(q.fX,     q.fY,     q.fZ);
+           glVertex3f(q.fX + w, q.fY,     q.fZ);
+           glVertex3f(q.fX + w, q.fY + h, q.fZ);
+           glVertex3f(q.fX,     q.fY + h, q.fZ);
+           glEnd();
+           ++qp;
+         }
+         break;
+       }
+
+       case QuadSet::QT_AxisAlignedFixedZ:
+       {
+         QuadSet::AAFixZQuad* qp = (QuadSet::AAFixZQuad*) qbp;
+         const Float_t& z = mQ.fDefCoord;
+         while (n--) {
+           QuadSet::AAFixZQuad& q = * qp;
+           if (SetupColor(q) == kFALSE) continue;
+           glBegin(GL_LINE_LOOP);
+           glVertex3f(q.fX,        q.fY,        z);
+           glVertex3f(q.fX + q.fW, q.fY,        z);
+           glVertex3f(q.fX + q.fW, q.fY + q.fH, z);
+           glVertex3f(q.fX,        q.fY + q.fH, z);
+           glEnd();
+           ++qp;
+         }
+         break;
+       }
+
+       case QuadSet::QT_AxisAlignedFixedY:
+       {
+         QuadSet::AAFixZQuad* qp = (QuadSet::AAFixZQuad*) qbp;
+         const Float_t& z = mQ.fDefCoord;
+         while (n--) {
+           QuadSet::AAFixZQuad& q = * qp;
+           if (SetupColor(q) == kFALSE) continue;
+           glBegin(GL_LINE_LOOP);
+           glVertex3f(q.fX,        z, q.fY);
+           glVertex3f(q.fX + q.fW, z, q.fY);
+           glVertex3f(q.fX + q.fW, z, q.fY + q.fH);
+           glVertex3f(q.fX,        z, q.fY + q.fH);
+           glEnd();
+           ++qp;
+         }
+         break;
+       }
+
+       case QuadSet::QT_AxisAlignedFixedDimZ:
+       {
+         QuadSet::AAFixDimZQuad* qp = (QuadSet::AAFixDimZQuad*) qbp;
+         const Float_t& z = mQ.fDefCoord;
+         const Float_t& w = mQ.fDefWidth;
+         const Float_t& h = mQ.fDefHeight;
+         while (n--) {
+           QuadSet::AAFixDimZQuad& q = * qp;
+           if (SetupColor(q) == kFALSE) continue;
+           glBegin(GL_LINE_LOOP);
+           glVertex3f(q.fX,     q.fY,     z);
+           glVertex3f(q.fX + w, q.fY,     z);
+           glVertex3f(q.fX + w, q.fY + h, z);
+           glVertex3f(q.fX,     q.fY + h, z);
+           glEnd();
+           ++qp;
+         }
+         break;
+       }
+
+       case QuadSet::QT_AxisAlignedFixedDimY:
+       {
+         QuadSet::AAFixDimZQuad* qp = (QuadSet::AAFixDimZQuad*) qbp;
+         const Float_t& z = mQ.fDefCoord;
+         const Float_t& w = mQ.fDefWidth;
+         const Float_t& h = mQ.fDefHeight;
+         while (n--) {
+           QuadSet::AAFixDimZQuad& q = * qp;
+           if (SetupColor(q) == kFALSE) continue;
+           glBegin(GL_LINE_LOOP);
+           glVertex3f(q.fX,     z, q.fY);
+           glVertex3f(q.fX + w, z, q.fY);
+           glVertex3f(q.fX + w, z, q.fY + h);
+           glVertex3f(q.fX,     z, q.fY + h);
+           glEnd();
+           ++qp;
+         }
+         break;
+       }
+
+       default:
+         throw(eH + "unsupported quad-type.");
+
+      } // end switch quad-type
+
+    } // end for chunk
+
+  } // end else of RenderMode
+}
+
+
+void QuadSetGL::RenderLines(const TGLDrawFlags &) const
+{
+  static const Exc_t eH("QuadSetGL::RenderLines ");
+
+  QuadSet& mQ = * fM;
+
+  for (Int_t c=0; c<mQ.fPlex.VecSize(); ++c)
+  {
+    QuadSet::QuadBase* qbp = (QuadSet::QuadBase*) mQ.fPlex.Chunk(c);
+    Int_t n = mQ.fPlex.NAtoms(c);
+
+    switch (mQ.fQuadType)
+    {
+
+      case QuadSet::QT_LineFixedZ:
+      {
+       QuadSet::LineFixedZ* qp = (QuadSet::LineFixedZ*) qbp;
+       const Float_t& z = mQ.fDefCoord;
+       glBegin(GL_LINES);
+       while (n--) {
+         QuadSet::LineFixedZ& q = * qp;
+         SetupColor(q);
+         glVertex3f(q.fX,         q.fY,         z);
+         glVertex3f(q.fX + q.fDx, q.fY + q.fDy, z);
+         ++qp;
+       }
+       glEnd();
+       break;
+      }
+
+      case QuadSet::QT_LineFixedY:
+      {
+       QuadSet::LineFixedZ* qp = (QuadSet::LineFixedZ*) qbp;
+       const Float_t& z = mQ.fDefCoord;
+       glBegin(GL_LINES);
+       while (n--) {
+         QuadSet::LineFixedZ& q = * qp;
+         SetupColor(q);
+         glVertex3f(q.fX,         z, q.fY);
+         glVertex3f(q.fX + q.fDx, z, q.fY + q.fDy);
+         ++qp;
+       }
+       glEnd();
+       break;
+      }
+
+      default:
+       throw(eH + "unsupported quad-type.");
+
+    }
+  }
+}
index e6f45c1..3a786b9 100644 (file)
@@ -4,6 +4,7 @@
 #define REVE_QuadSetGL_H
 
 #include <TGLObject.h>
+#include <Reve/QuadSet.h>
 
 namespace Reve {
 
@@ -22,6 +23,31 @@ public:
   ClassDef(OldQuadSetGL, 0);
 };
 
+/**************************************************************************/
+/**************************************************************************/
+
+class QuadSetGL : public TGLObject
+{
+protected:
+  QuadSet* fM;
+
+  virtual void DirectDraw(const TGLDrawFlags & flags) const;
+
+  Bool_t SetupColor(const QuadSet::QuadBase& q) const;
+
+  void   RenderQuads(const TGLDrawFlags & flags) const;
+  void   RenderLines(const TGLDrawFlags & flags) const;
+
+public:
+  QuadSetGL();
+  virtual ~QuadSetGL();
+
+  virtual Bool_t SetModel(TObject* obj);
+  virtual void   SetBBox();
+
+  ClassDef(QuadSetGL, 0);
+};
+
 }
 
 #endif