// $Header$
#include "QuadSetGL.h"
-#include <Reve/QuadSet.h>
+#include <Reve/FrameBoxGL.h>
#include <TGLDrawFlags.h>
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);
+ return kTRUE;
+ }
+ else
+ {
+ UChar_t c[4];
+ Bool_t visible = fM->fPalette->ColorFromValue(q.fValue, fM->fDefaultValue, c);
+ if (visible)
+ glColor4ubv(c);
+ return visible;
+ }
+}
+
+/**************************************************************************/
+
+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.fFrame != 0)
+ FrameBoxGL::Render(mQ.fFrame);
+
+ if (mQ.fPlex.Size() == 0)
+ return;
+ if ( ! mQ.fValueIsColor && mQ.fPalette == 0)
+ {
+ mQ.AssertPalette();
+ }
+
+ 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);
+
+ if (mQ.fDisableLigting) glDisable(GL_LIGHTING);
+
+ if (mQ.fQuadType < QuadSet::QT_Rectangle_End) RenderQuads(flags);
+ else if (mQ.fQuadType < QuadSet::QT_Line_End) RenderLines(flags);
+ else if (mQ.fQuadType < QuadSet::QT_Hexagon_End) RenderHexagons(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::QFreeQuad* qp = (QuadSet::QFreeQuad*) qbp;
+ Float_t e1[3], e2[3], normal[3];
+ while (n--) {
+ if (SetupColor(*qp))
+ {
+ 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_RectangleXY:
+ {
+ QuadSet::QRect* qp = (QuadSet::QRect*) qbp;
+ while (n--) {
+ QuadSet::QRect& q = * qp;
+ if (SetupColor(q))
+ {
+ 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_RectangleXYFixedDim:
+ {
+ QuadSet::QRectFixDim* qp = (QuadSet::QRectFixDim*) qbp;
+ const Float_t& w = mQ.fDefWidth;
+ const Float_t& h = mQ.fDefHeight;
+ while (n--) {
+ QuadSet::QRectFixDim& q = * qp;
+ if (SetupColor(q))
+ {
+ 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_RectangleXYFixedZ:
+ {
+ QuadSet::QRectFixC* qp = (QuadSet::QRectFixC*) qbp;
+ const Float_t& z = mQ.fDefCoord;
+ while (n--) {
+ QuadSet::QRectFixC& q = * qp;
+ if (SetupColor(q))
+ {
+ 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_RectangleXZFixedY:
+ {
+ QuadSet::QRectFixC* qp = (QuadSet::QRectFixC*) qbp;
+ const Float_t& z = mQ.fDefCoord;
+ while (n--) {
+ QuadSet::QRectFixC& q = * qp;
+ if (SetupColor(q))
+ {
+ 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_RectangleXYFixedDimZ:
+ {
+ QuadSet::QRectFixDimC* qp = (QuadSet::QRectFixDimC*) qbp;
+ const Float_t& z = mQ.fDefCoord;
+ const Float_t& w = mQ.fDefWidth;
+ const Float_t& h = mQ.fDefHeight;
+ while (n--) {
+ QuadSet::QRectFixDimC& q = * qp;
+ if (SetupColor(q))
+ {
+ 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_RectangleXZFixedDimY:
+ {
+ QuadSet::QRectFixDimC* qp = (QuadSet::QRectFixDimC*) qbp;
+ const Float_t& z = mQ.fDefCoord;
+ const Float_t& w = mQ.fDefWidth;
+ const Float_t& h = mQ.fDefHeight;
+ while (n--) {
+ QuadSet::QRectFixDimC& q = * qp;
+ if (SetupColor(q))
+ {
+ 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::QFreeQuad* qp = (QuadSet::QFreeQuad*) qbp;
+ while (n--) {
+ if (SetupColor(*qp))
+ {
+ 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_RectangleXY:
+ {
+ QuadSet::QRect* qp = (QuadSet::QRect*) qbp;
+ while (n--) {
+ QuadSet::QRect& q = * qp;
+ if (SetupColor(q))
+ {
+ 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_RectangleXYFixedDim:
+ {
+ QuadSet::QRectFixDim* qp = (QuadSet::QRectFixDim*) qbp;
+ const Float_t& w = mQ.fDefWidth;
+ const Float_t& h = mQ.fDefHeight;
+ while (n--) {
+ QuadSet::QRectFixDim& q = * qp;
+ if (SetupColor(q))
+ {
+ 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_RectangleXYFixedZ:
+ {
+ QuadSet::QRectFixC* qp = (QuadSet::QRectFixC*) qbp;
+ const Float_t& z = mQ.fDefCoord;
+ while (n--) {
+ QuadSet::QRectFixC& q = * qp;
+ if (SetupColor(q))
+ {
+ 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_RectangleXZFixedY:
+ {
+ QuadSet::QRectFixC* qp = (QuadSet::QRectFixC*) qbp;
+ const Float_t& z = mQ.fDefCoord;
+ while (n--) {
+ QuadSet::QRectFixC& q = * qp;
+ if (SetupColor(q))
+ {
+ 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_RectangleXYFixedDimZ:
+ {
+ QuadSet::QRectFixDimC* qp = (QuadSet::QRectFixDimC*) qbp;
+ const Float_t& z = mQ.fDefCoord;
+ const Float_t& w = mQ.fDefWidth;
+ const Float_t& h = mQ.fDefHeight;
+ while (n--) {
+ QuadSet::QRectFixDimC& q = * qp;
+ if (SetupColor(q))
+ {
+ 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_RectangleXZFixedDimY:
+ {
+ QuadSet::QRectFixDimC* qp = (QuadSet::QRectFixDimC*) qbp;
+ const Float_t& z = mQ.fDefCoord;
+ const Float_t& w = mQ.fDefWidth;
+ const Float_t& h = mQ.fDefHeight;
+ while (n--) {
+ QuadSet::QRectFixDimC& q = * qp;
+ if (SetupColor(q))
+ {
+ 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_LineXYFixedZ:
+ {
+ QuadSet::QLineFixC* qp = (QuadSet::QLineFixC*) qbp;
+ const Float_t& z = mQ.fDefCoord;
+ glBegin(GL_LINES);
+ while (n--) {
+ QuadSet::QLineFixC& q = * qp;
+ if (SetupColor(q))
+ {
+ glVertex3f(q.fX, q.fY, z);
+ glVertex3f(q.fX + q.fDx, q.fY + q.fDy, z);
+ }
+ ++qp;
+ }
+ glEnd();
+ break;
+ }
+
+ case QuadSet::QT_LineXZFixedY:
+ {
+ QuadSet::QLineFixC* qp = (QuadSet::QLineFixC*) qbp;
+ const Float_t& z = mQ.fDefCoord;
+ glBegin(GL_LINES);
+ while (n--) {
+ QuadSet::QLineFixC& q = * qp;
+ if (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.");
+
+ }
+ }
+}
+
+void QuadSetGL::RenderHexagons(const TGLDrawFlags &) const
+{
+ static const Exc_t eH("QuadSetGL::RenderHexagons ");
+
+ const Float_t sqr3hf = 0.5*TMath::Sqrt(3);
+
+ QuadSet& mQ = * fM;
+
+ if (mQ.fRenderMode != QuadSet::RM_Line)
+ {
+
+ glNormal3f(0, 0, 1);
+
+ 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_HexagonXY:
+ {
+ QuadSet::QHex* qp = (QuadSet::QHex*) qbp;
+ while (n--) {
+ QuadSet::QHex& q = * qp;
+ if (SetupColor(q))
+ {
+ const Float_t rh = q.fR * 0.5;
+ const Float_t rs = q.fR * sqr3hf;
+ glBegin(GL_POLYGON);
+ glVertex3f( q.fR + q.fX, q.fY, q.fZ);
+ glVertex3f( rh + q.fX, rs + q.fY, q.fZ);
+ glVertex3f( -rh + q.fX, rs + q.fY, q.fZ);
+ glVertex3f(-q.fR + q.fX, q.fY, q.fZ);
+ glVertex3f( -rh + q.fX, -rs + q.fY, q.fZ);
+ glVertex3f( rh + q.fX, -rs + q.fY, q.fZ);
+ glEnd();
+ }
+ ++qp;
+ }
+ break;
+ }
+
+ case QuadSet::QT_HexagonYX:
+ {
+ QuadSet::QHex* qp = (QuadSet::QHex*) qbp;
+ while (n--) {
+ QuadSet::QHex& q = * qp;
+ if (SetupColor(q))
+ {
+ const Float_t rh = q.fR * 0.5;
+ const Float_t rs = q.fR * sqr3hf;
+ glBegin(GL_POLYGON);
+ glVertex3f( rs + q.fX, rh + q.fY, q.fZ);
+ glVertex3f( q.fX, q.fR + q.fY, q.fZ);
+ glVertex3f(-rs + q.fX, rh + q.fY, q.fZ);
+ glVertex3f(-rs + q.fX, -rh + q.fY, q.fZ);
+ glVertex3f( q.fX, -q.fR + q.fY, q.fZ);
+ glVertex3f( rs + q.fX, -rh + q.fY, q.fZ);
+ glEnd();
+ }
+ ++qp;
+ }
+ break;
+ }
+
+ default:
+ throw(eH + "unsupported quad-type.");
+
+ } // end switch quad-type
+
+ } // end for chunk
+
+ }
+ 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_HexagonXY:
+ {
+ QuadSet::QHex* qp = (QuadSet::QHex*) qbp;
+ while (n--) {
+ QuadSet::QHex& q = * qp;
+ if (SetupColor(q))
+ {
+ const Float_t rh = q.fR * 0.5;
+ const Float_t rs = q.fR * sqr3hf;
+ glBegin(GL_LINE_LOOP);
+ glVertex3f( q.fR + q.fX, q.fY, q.fZ);
+ glVertex3f( rh + q.fX, rs + q.fY, q.fZ);
+ glVertex3f( -rh + q.fX, rs + q.fY, q.fZ);
+ glVertex3f(-q.fR + q.fX, q.fY, q.fZ);
+ glVertex3f( -rh + q.fX, -rs + q.fY, q.fZ);
+ glVertex3f( rh + q.fX, -rs + q.fY, q.fZ);
+ glEnd();
+ }
+ ++qp;
+ }
+ break;
+ }
+
+ case QuadSet::QT_HexagonYX:
+ {
+ QuadSet::QHex* qp = (QuadSet::QHex*) qbp;
+ while (n--) {
+ QuadSet::QHex& q = * qp;
+ if (SetupColor(q))
+ {
+ const Float_t rh = q.fR * 0.5;
+ const Float_t rs = q.fR * sqr3hf;
+ glBegin(GL_LINE_LOOP);
+ glVertex3f( rs + q.fX, rh + q.fY, q.fZ);
+ glVertex3f( q.fX, q.fR + q.fY, q.fZ);
+ glVertex3f(-rs + q.fX, rh + q.fY, q.fZ);
+ glVertex3f(-rs + q.fX, -rh + q.fY, q.fZ);
+ glVertex3f( q.fX, -q.fR + q.fY, q.fZ);
+ glVertex3f( rs + q.fX, -rh + q.fY, q.fZ);
+ glEnd();
+ }
+ ++qp;
+ }
+ break;
+ }
+
+ default:
+ throw(eH + "unsupported quad-type.");
+
+ } // end switch quad-type
+
+ } // end for chunk
+
+ } // end else of RenderMode
+
+
+}