00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012 #include "TMath.h"
00013
00014 #include "TEveQuadSetGL.h"
00015 #include "TEveFrameBoxGL.h"
00016
00017 #include "TGLRnrCtx.h"
00018 #include "TGLIncludes.h"
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028 ClassImp(TEveQuadSetGL);
00029
00030
00031
00032
00033 TEveQuadSetGL::TEveQuadSetGL() : TEveDigitSetGL(), fM(0)
00034 {
00035
00036
00037
00038 fMultiColor = kTRUE;
00039 }
00040
00041
00042
00043
00044 Bool_t TEveQuadSetGL::SetModel(TObject* obj, const Option_t* )
00045 {
00046
00047
00048 fM = SetModelDynCast<TEveQuadSet>(obj);
00049 return kTRUE;
00050 }
00051
00052
00053
00054 namespace
00055 {
00056 inline void AntiFlick(Float_t x, Float_t y, Float_t z)
00057 {
00058
00059 glBegin(GL_POINTS);
00060 glVertex3f(x, y, z);
00061 glEnd();
00062 }
00063 }
00064
00065
00066 void TEveQuadSetGL::DirectDraw(TGLRnrCtx & rnrCtx) const
00067 {
00068
00069
00070 static const TEveException eH("TEveQuadSetGL::DirectDraw ");
00071
00072
00073
00074 TEveQuadSet& mQ = * fM;
00075
00076 if (mQ.fPlex.Size() > 0)
00077 {
00078 if (! mQ.fSingleColor && ! mQ.fValueIsColor && mQ.fPalette == 0)
00079 {
00080 mQ.AssertPalette();
00081 }
00082
00083 glPushAttrib(GL_ENABLE_BIT | GL_POLYGON_BIT);
00084 glColorMaterial(GL_FRONT_AND_BACK, GL_DIFFUSE);
00085 glEnable(GL_COLOR_MATERIAL);
00086 glDisable(GL_CULL_FACE);
00087
00088 if ( ! rnrCtx.IsDrawPassOutlineLine())
00089 {
00090 if (mQ.fRenderMode == TEveDigitSet::kRM_Fill)
00091 glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
00092 else if (mQ.fRenderMode == TEveDigitSet::kRM_Line)
00093 glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
00094 }
00095
00096 if (mQ.fDisableLighting) glDisable(GL_LIGHTING);
00097
00098 if (mQ.fQuadType < TEveQuadSet::kQT_Rectangle_End) RenderQuads(rnrCtx);
00099 else if (mQ.fQuadType < TEveQuadSet::kQT_Line_End) RenderLines(rnrCtx);
00100 else if (mQ.fQuadType < TEveQuadSet::kQT_Hexagon_End) RenderHexagons(rnrCtx);
00101
00102 glPopAttrib();
00103 }
00104
00105 if (mQ.fFrame != 0 && ! rnrCtx.SecSelection() &&
00106 ! (rnrCtx.Highlight() && AlwaysSecondarySelect()))
00107 {
00108 TEveFrameBoxGL::Render(mQ.fFrame);
00109 }
00110 }
00111
00112
00113 void TEveQuadSetGL::RenderQuads(TGLRnrCtx& rnrCtx) const
00114 {
00115
00116
00117 static const TEveException eH("TEveQuadSetGL::RenderQuads ");
00118
00119 TEveQuadSet& mQ = * fM;
00120
00121 GLenum primitiveType;
00122 if (mQ.fRenderMode != TEveDigitSet::kRM_Line)
00123 {
00124 primitiveType = GL_QUADS;
00125 if (mQ.fQuadType == TEveQuadSet::kQT_FreeQuad)
00126 glEnable(GL_NORMALIZE);
00127 else
00128 glNormal3f(0, 0, 1);
00129 } else {
00130 primitiveType = GL_LINE_LOOP;
00131 }
00132
00133 TEveChunkManager::iterator qi(mQ.fPlex);
00134 if (rnrCtx.Highlight() && fHighlightSet)
00135 qi.fSelection = fHighlightSet;
00136
00137 if (rnrCtx.SecSelection()) glPushName(0);
00138
00139 switch (mQ.fQuadType)
00140 {
00141
00142 case TEveQuadSet::kQT_FreeQuad:
00143 {
00144 Float_t e1[3], e2[3], normal[3];
00145 while (qi.next()) {
00146 TEveQuadSet::QFreeQuad_t& q = * (TEveQuadSet::QFreeQuad_t*) qi();
00147 if (SetupColor(q))
00148 {
00149 Float_t* p = q.fVertices;
00150 e1[0] = p[3] - p[0]; e1[1] = p[4] - p[1]; e1[2] = p[5] - p[2];
00151 e2[0] = p[6] - p[0]; e2[1] = p[7] - p[1]; e2[2] = p[8] - p[2];
00152 TMath::Cross(e1, e2, normal);
00153 if (rnrCtx.SecSelection()) glLoadName(qi.index());
00154 glBegin(primitiveType);
00155 glNormal3fv(normal);
00156 glVertex3fv(p);
00157 glVertex3fv(p + 3);
00158 glVertex3fv(p + 6);
00159 glVertex3fv(p + 9);
00160 glEnd();
00161 if (mQ.fAntiFlick)
00162 AntiFlick(0.5f*(p[0]+p[6]), 0.5f*(p[1]+p[7]), 0.5f*(p[2]+p[8]));
00163 }
00164 }
00165 break;
00166 }
00167
00168 case TEveQuadSet::kQT_RectangleXY:
00169 {
00170 while (qi.next()) {
00171 TEveQuadSet::QRect_t& q = * (TEveQuadSet::QRect_t*) qi();
00172 if (SetupColor(q))
00173 {
00174 if (rnrCtx.SecSelection()) glLoadName(qi.index());
00175 glBegin(primitiveType);
00176 glVertex3f(q.fA, q.fB, q.fC);
00177 glVertex3f(q.fA + q.fW, q.fB, q.fC);
00178 glVertex3f(q.fA + q.fW, q.fB + q.fH, q.fC);
00179 glVertex3f(q.fA, q.fB + q.fH, q.fC);
00180 glEnd();
00181 if (mQ.fAntiFlick)
00182 AntiFlick(q.fA + 0.5f*q.fW, q.fB + 0.5f*q.fH, q.fC);
00183 }
00184 }
00185 break;
00186 }
00187
00188 case TEveQuadSet::kQT_RectangleXZ:
00189 {
00190 while (qi.next()) {
00191 TEveQuadSet::QRect_t& q = * (TEveQuadSet::QRect_t*) qi();
00192 if (SetupColor(q))
00193 {
00194 if (rnrCtx.SecSelection()) glLoadName(qi.index());
00195 glBegin(primitiveType);
00196 glVertex3f(q.fA, q.fC, q.fB);
00197 glVertex3f(q.fA + q.fW, q.fC, q.fB);
00198 glVertex3f(q.fA + q.fW, q.fC, q.fB + q.fH);
00199 glVertex3f(q.fA, q.fC, q.fB + q.fH);
00200 glEnd();
00201 if (mQ.fAntiFlick)
00202 AntiFlick(q.fA + 0.5f*q.fW, q.fC, q.fB + 0.5f*q.fH);
00203 }
00204 }
00205 break;
00206 }
00207
00208 case TEveQuadSet::kQT_RectangleYZ:
00209 {
00210 while (qi.next()) {
00211 TEveQuadSet::QRect_t& q = * (TEveQuadSet::QRect_t*) qi();
00212 if (SetupColor(q))
00213 {
00214 if (rnrCtx.SecSelection()) glLoadName(qi.index());
00215 glBegin(primitiveType);
00216 glVertex3f(q.fC, q.fA, q.fB);
00217 glVertex3f(q.fC, q.fA + q.fW, q.fB);
00218 glVertex3f(q.fC, q.fA + q.fW, q.fB + q.fH);
00219 glVertex3f(q.fC, q.fA, q.fB + q.fH);
00220 glEnd();
00221 if (mQ.fAntiFlick)
00222 AntiFlick(q.fC, q.fA + 0.5f*q.fW, q.fB + 0.5f*q.fH);
00223 }
00224 }
00225 break;
00226 }
00227
00228 case TEveQuadSet::kQT_RectangleXYFixedDim:
00229 {
00230 const Float_t& w = mQ.fDefWidth;
00231 const Float_t& h = mQ.fDefHeight;
00232 while (qi.next()) {
00233 TEveQuadSet::QRectFixDim_t& q = * (TEveQuadSet::QRectFixDim_t*) qi();
00234 if (SetupColor(q))
00235 {
00236 if (rnrCtx.SecSelection()) glLoadName(qi.index());
00237 glBegin(primitiveType);
00238 glVertex3f(q.fA, q.fB, q.fC);
00239 glVertex3f(q.fA + w, q.fB, q.fC);
00240 glVertex3f(q.fA + w, q.fB + h, q.fC);
00241 glVertex3f(q.fA, q.fB + h, q.fC);
00242 glEnd();
00243 glEnd();
00244 if (mQ.fAntiFlick)
00245 AntiFlick(q.fA + 0.5f*w, q.fB + 0.5f*h, q.fC);
00246 }
00247 }
00248 break;
00249 }
00250
00251 case TEveQuadSet::kQT_RectangleXYFixedZ:
00252 {
00253 const Float_t& z = mQ.fDefCoord;
00254 while (qi.next()) {
00255 TEveQuadSet::QRectFixC_t& q = * (TEveQuadSet::QRectFixC_t*) qi();
00256 if (SetupColor(q))
00257 {
00258 if (rnrCtx.SecSelection()) glLoadName(qi.index());
00259 glBegin(primitiveType);
00260 glVertex3f(q.fA, q.fB, z);
00261 glVertex3f(q.fA + q.fW, q.fB, z);
00262 glVertex3f(q.fA + q.fW, q.fB + q.fH, z);
00263 glVertex3f(q.fA, q.fB + q.fH, z);
00264 glEnd();
00265 if (mQ.fAntiFlick)
00266 AntiFlick(q.fA + 0.5f*q.fW, q.fB + 0.5f*q.fH, z);
00267 }
00268 }
00269 break;
00270 }
00271
00272 case TEveQuadSet::kQT_RectangleXZFixedY:
00273 {
00274 const Float_t& y = mQ.fDefCoord;
00275 while (qi.next()) {
00276 TEveQuadSet::QRectFixC_t& q = * (TEveQuadSet::QRectFixC_t*) qi();
00277 if (SetupColor(q))
00278 {
00279 if (rnrCtx.SecSelection()) glLoadName(qi.index());
00280 glBegin(primitiveType);
00281 glVertex3f(q.fA, y, q.fB);
00282 glVertex3f(q.fA + q.fW, y, q.fB);
00283 glVertex3f(q.fA + q.fW, y, q.fB + q.fH);
00284 glVertex3f(q.fA, y, q.fB + q.fH);
00285 glEnd();
00286 if (mQ.fAntiFlick)
00287 AntiFlick(q.fA + 0.5f*q.fW, y, q.fB + 0.5f*q.fH);
00288 }
00289 }
00290 break;
00291 }
00292
00293 case TEveQuadSet::kQT_RectangleYZFixedX:
00294 {
00295 const Float_t& x = mQ.fDefCoord;
00296 while (qi.next()) {
00297 TEveQuadSet::QRectFixC_t& q = * (TEveQuadSet::QRectFixC_t*) qi();
00298 if (SetupColor(q))
00299 {
00300 if (rnrCtx.SecSelection()) glLoadName(qi.index());
00301 glBegin(primitiveType);
00302 glVertex3f(x, q.fA, q.fB);
00303 glVertex3f(x, q.fA + q.fW, q.fB);
00304 glVertex3f(x, q.fA + q.fW, q.fB + q.fH);
00305 glVertex3f(x, q.fA, q.fB + q.fH);
00306 glEnd();
00307 if (mQ.fAntiFlick)
00308 AntiFlick(x, q.fA + 0.5f*q.fW, q.fB + 0.5f*q.fH);
00309 }
00310 }
00311 break;
00312 }
00313
00314 case TEveQuadSet::kQT_RectangleXYFixedDimZ:
00315 {
00316 const Float_t& z = mQ.fDefCoord;
00317 const Float_t& w = mQ.fDefWidth;
00318 const Float_t& h = mQ.fDefHeight;
00319 while (qi.next()) {
00320 TEveQuadSet::QRectFixDimC_t& q = * (TEveQuadSet::QRectFixDimC_t*) qi();
00321 if (SetupColor(q))
00322 {
00323 if (rnrCtx.SecSelection()) glLoadName(qi.index());
00324 glBegin(primitiveType);
00325 glVertex3f(q.fA, q.fB, z);
00326 glVertex3f(q.fA + w, q.fB, z);
00327 glVertex3f(q.fA + w, q.fB + h, z);
00328 glVertex3f(q.fA, q.fB + h, z);
00329 glEnd();
00330 if (mQ.fAntiFlick)
00331 AntiFlick(q.fA + 0.5f*w, q.fB + 0.5f*h, z);
00332 }
00333 }
00334 break;
00335 }
00336
00337 case TEveQuadSet::kQT_RectangleXZFixedDimY:
00338 {
00339 const Float_t& y = mQ.fDefCoord;
00340 const Float_t& w = mQ.fDefWidth;
00341 const Float_t& h = mQ.fDefHeight;
00342 while (qi.next()) {
00343 TEveQuadSet::QRectFixDimC_t& q = * (TEveQuadSet::QRectFixDimC_t*) qi();
00344 if (SetupColor(q))
00345 {
00346 if (rnrCtx.SecSelection()) glLoadName(qi.index());
00347 glBegin(primitiveType);
00348 glVertex3f(q.fA, y, q.fB);
00349 glVertex3f(q.fA + w, y, q.fB);
00350 glVertex3f(q.fA + w, y, q.fB + h);
00351 glVertex3f(q.fA, y, q.fB + h);
00352 glEnd();
00353 if (mQ.fAntiFlick)
00354 AntiFlick(q.fA + 0.5f*w, y, q.fB + 0.5f*h);
00355 }
00356 }
00357 break;
00358 }
00359
00360 case TEveQuadSet::kQT_RectangleYZFixedDimX:
00361 {
00362 const Float_t& x = mQ.fDefCoord;
00363 const Float_t& w = mQ.fDefWidth;
00364 const Float_t& h = mQ.fDefHeight;
00365 while (qi.next()) {
00366 TEveQuadSet::QRectFixDimC_t& q = * (TEveQuadSet::QRectFixDimC_t*) qi();
00367 if (SetupColor(q))
00368 {
00369 if (rnrCtx.SecSelection()) glLoadName(qi.index());
00370 glBegin(primitiveType);
00371 glVertex3f(x, q.fA, q.fB);
00372 glVertex3f(x, q.fA + w, q.fB);
00373 glVertex3f(x, q.fA + w, q.fB + h);
00374 glVertex3f(x, q.fA, q.fB + h);
00375 glEnd();
00376 if (mQ.fAntiFlick)
00377 AntiFlick(x, q.fA + 0.5f*w, q.fB + 0.5f*h);
00378 }
00379 }
00380 break;
00381 }
00382
00383 default:
00384 throw(eH + "unsupported quad-type.");
00385
00386 }
00387
00388 if (rnrCtx.SecSelection()) glPopName();
00389 }
00390
00391
00392 void TEveQuadSetGL::RenderLines(TGLRnrCtx & rnrCtx) const
00393 {
00394
00395
00396 static const TEveException eH("TEveQuadSetGL::RenderLines ");
00397
00398 TEveQuadSet& mQ = * fM;
00399
00400 TEveChunkManager::iterator qi(mQ.fPlex);
00401 if (rnrCtx.Highlight() && fHighlightSet)
00402 qi.fSelection = fHighlightSet;
00403
00404 if (rnrCtx.SecSelection()) glPushName(0);
00405
00406 switch (mQ.fQuadType)
00407 {
00408
00409 case TEveQuadSet::kQT_LineXYFixedZ:
00410 {
00411 const Float_t& z = mQ.fDefCoord;
00412 while (qi.next()) {
00413 TEveQuadSet::QLineFixC_t& q = * (TEveQuadSet::QLineFixC_t*) qi();
00414 if (SetupColor(q))
00415 {
00416 if (rnrCtx.SecSelection()) glLoadName(qi.index());
00417 glBegin(GL_LINES);
00418 glVertex3f(q.fA, q.fB, z);
00419 glVertex3f(q.fA + q.fDx, q.fB + q.fDy, z);
00420 glEnd();
00421 }
00422 }
00423 break;
00424 }
00425
00426 case TEveQuadSet::kQT_LineXZFixedY:
00427 {
00428 const Float_t& z = mQ.fDefCoord;
00429 while (qi.next()) {
00430 TEveQuadSet::QLineFixC_t& q = * (TEveQuadSet::QLineFixC_t*) qi();
00431 if (SetupColor(q))
00432 {
00433 if (rnrCtx.SecSelection()) glLoadName(qi.index());
00434 glBegin(GL_LINES);
00435 glVertex3f(q.fA, z, q.fB);
00436 glVertex3f(q.fA + q.fDx, z, q.fB + q.fDy);
00437 glEnd();
00438 }
00439 }
00440 break;
00441 }
00442
00443 default:
00444 throw(eH + "unsupported quad-type.");
00445
00446 }
00447
00448 if (rnrCtx.SecSelection()) glPopName();
00449 }
00450
00451
00452 void TEveQuadSetGL::RenderHexagons(TGLRnrCtx & rnrCtx) const
00453 {
00454
00455
00456 static const TEveException eH("TEveQuadSetGL::RenderHexagons ");
00457
00458 const Float_t sqr3hf = 0.5*TMath::Sqrt(3);
00459
00460 TEveQuadSet& mQ = * fM;
00461
00462 GLenum primitveType = (mQ.fRenderMode != TEveDigitSet::kRM_Line) ?
00463 GL_POLYGON : GL_LINE_LOOP;
00464
00465 glNormal3f(0, 0, 1);
00466
00467 TEveChunkManager::iterator qi(mQ.fPlex);
00468 if (rnrCtx.Highlight() && fHighlightSet)
00469 qi.fSelection = fHighlightSet;
00470
00471 if (rnrCtx.SecSelection()) glPushName(0);
00472
00473 switch (mQ.fQuadType)
00474 {
00475
00476 case TEveQuadSet::kQT_HexagonXY:
00477 {
00478 while (qi.next()) {
00479 TEveQuadSet::QHex_t& q = * (TEveQuadSet::QHex_t*) qi();
00480 if (SetupColor(q))
00481 {
00482 const Float_t rh = q.fR * 0.5;
00483 const Float_t rs = q.fR * sqr3hf;
00484 if (rnrCtx.SecSelection()) glLoadName(qi.index());
00485 glBegin(primitveType);
00486 glVertex3f( q.fR + q.fA, q.fB, q.fC);
00487 glVertex3f( rh + q.fA, rs + q.fB, q.fC);
00488 glVertex3f( -rh + q.fA, rs + q.fB, q.fC);
00489 glVertex3f(-q.fR + q.fA, q.fB, q.fC);
00490 glVertex3f( -rh + q.fA, -rs + q.fB, q.fC);
00491 glVertex3f( rh + q.fA, -rs + q.fB, q.fC);
00492 glEnd();
00493 if (mQ.fAntiFlick)
00494 AntiFlick(q.fA, q.fB, q.fC);
00495 }
00496 }
00497 break;
00498 }
00499
00500 case TEveQuadSet::kQT_HexagonYX:
00501 {
00502 while (qi.next()) {
00503 TEveQuadSet::QHex_t& q = * (TEveQuadSet::QHex_t*) qi();
00504 if (SetupColor(q))
00505 {
00506 const Float_t rh = q.fR * 0.5;
00507 const Float_t rs = q.fR * sqr3hf;
00508 if (rnrCtx.SecSelection()) glLoadName(qi.index());
00509 glBegin(primitveType);
00510 glVertex3f( rs + q.fA, rh + q.fB, q.fC);
00511 glVertex3f( q.fA, q.fR + q.fB, q.fC);
00512 glVertex3f(-rs + q.fA, rh + q.fB, q.fC);
00513 glVertex3f(-rs + q.fA, -rh + q.fB, q.fC);
00514 glVertex3f( q.fA, -q.fR + q.fB, q.fC);
00515 glVertex3f( rs + q.fA, -rh + q.fB, q.fC);
00516 glEnd();
00517 if (mQ.fAntiFlick)
00518 AntiFlick(q.fA, q.fB, q.fC);
00519 }
00520 }
00521 break;
00522 }
00523
00524 default:
00525 throw(eH + "unsupported quad-type.");
00526
00527 }
00528
00529 if (rnrCtx.SecSelection()) glPopName();
00530 }