Line data Source code
1 : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : /*
3 : * This file is part of the LibreOffice project.
4 : *
5 : * This Source Code Form is subject to the terms of the Mozilla Public
6 : * License, v. 2.0. If a copy of the MPL was not distributed with this
7 : * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 : */
9 :
10 : #include <GL3DBarChart.hxx>
11 :
12 : #include <GL/glew.h>
13 :
14 : #include <glm/glm.hpp>
15 : #include <glm/gtx/transform.hpp>
16 :
17 : #include "3DChartObjects.hxx"
18 : #include "GL3DRenderer.hxx"
19 : #include <ExplicitCategoriesProvider.hxx>
20 : #include <DataSeriesHelper.hxx>
21 :
22 : #include <osl/time.h>
23 : #ifdef WNT
24 : #include <windows.h>
25 : #endif
26 :
27 : #define CALC_POS_EVENT_ID 1
28 : #define SHAPE_START_ID 10
29 : #define FPS_TIME 500
30 : #define DATAUPDATE_FPS_TIME 1000
31 : #define HISTORY_NUM 51
32 : #define COLUMNSIZE 25
33 : #define SHOW_VALUE_COUNT 15
34 : #define SHOW_SCROLL_TEXT_DISTANCE 1000
35 : #define FLY_THRESHOLD 20
36 : #define DISPLAY_BARS_NUM 3
37 :
38 :
39 : using namespace com::sun::star;
40 :
41 : namespace chart {
42 :
43 : const size_t STEPS = 200;
44 : const size_t STEPS_UPDATE = 100;
45 : namespace {
46 :
47 : const float TEXT_HEIGHT = 10.0f;
48 : float DEFAULT_CAMERA_HEIGHT = 500.0f;
49 : const sal_uInt32 ID_STEP = 10;
50 :
51 : #if 0
52 : const float BAR_SIZE_X = 15.0f;
53 : const float BAR_SIZE_Y = 15.0f;
54 : #else
55 : const float BAR_SIZE_X = 30.0f;
56 : const float BAR_SIZE_Y = 5.0f;
57 : #endif
58 : const float BAR_DISTANCE_X = 5.0f;
59 : const float BAR_DISTANCE_Y = 5.0;
60 :
61 0 : float calculateTextWidth(const OUString& rText)
62 : {
63 0 : return rText.getLength() * 10;
64 : }
65 :
66 0 : double findMaxValue(const boost::ptr_vector<VDataSeries>& rDataSeriesContainer)
67 : {
68 0 : double nMax = 0.0;
69 0 : for (boost::ptr_vector<VDataSeries>::const_iterator itr = rDataSeriesContainer.begin(),
70 0 : itrEnd = rDataSeriesContainer.end(); itr != itrEnd; ++itr)
71 : {
72 0 : const VDataSeries& rDataSeries = *itr;
73 0 : sal_Int32 nPointCount = rDataSeries.getTotalPointCount();
74 0 : for(sal_Int32 nIndex = 0; nIndex < nPointCount; ++nIndex)
75 : {
76 0 : double nVal = rDataSeries.getYValue(nIndex);
77 0 : nMax = std::max(nMax, nVal);
78 : }
79 : }
80 0 : return nMax;
81 : }
82 :
83 : class SharedResourceAccess
84 : {
85 : private:
86 : osl::Condition& mrCond1;
87 : osl::Condition& mrCond2;
88 :
89 : public:
90 :
91 0 : SharedResourceAccess(osl::Condition& rCond1, osl::Condition& rCond2):
92 : mrCond1(rCond1),
93 0 : mrCond2(rCond2)
94 : {
95 0 : mrCond1.set();
96 0 : }
97 :
98 0 : ~SharedResourceAccess()
99 : {
100 0 : mrCond2.set();
101 0 : }
102 : };
103 :
104 : }
105 :
106 0 : class RenderThread : public salhelper::Thread
107 : {
108 : public:
109 : explicit RenderThread(GL3DBarChart* pChart);
110 :
111 : protected:
112 :
113 : void renderFrame();
114 : GL3DBarChart* mpChart;
115 : };
116 :
117 0 : RenderThread::RenderThread(GL3DBarChart* pChart):
118 : salhelper::Thread("RenderThread"),
119 0 : mpChart(pChart)
120 : {
121 0 : }
122 :
123 0 : void RenderThread::renderFrame()
124 : {
125 0 : if(!mpChart->mbValidContext)
126 0 : return;
127 :
128 0 : mpChart->mpWindow->getContext().makeCurrent();
129 0 : mpChart->renderFrame();
130 : // FIXME: SwapBuffers can take a considerable time, it'd be
131 : // nice if we didn't hold the chart mutex while doing that.
132 0 : mpChart->mpWindow->getContext().swapBuffers();
133 0 : mpChart->mpWindow->getContext().resetCurrent();
134 : }
135 :
136 0 : class RenderOneFrameThread : public RenderThread
137 : {
138 : public:
139 0 : explicit RenderOneFrameThread(GL3DBarChart* pChart):
140 0 : RenderThread(pChart)
141 0 : {}
142 :
143 : protected:
144 :
145 : virtual void execute() SAL_OVERRIDE;
146 : };
147 :
148 0 : void RenderOneFrameThread::execute()
149 : {
150 0 : osl::MutexGuard aGuard(mpChart->maMutex);
151 0 : renderFrame();
152 0 : }
153 :
154 0 : class RenderAnimationThread : public RenderThread
155 : {
156 : public:
157 0 : RenderAnimationThread(GL3DBarChart* pChart, const glm::vec3& rStartPos, const glm::vec3& rEndPos,
158 : const sal_Int32 nSteps = STEPS):
159 : RenderThread(pChart),
160 : maStartPos(rStartPos),
161 : maEndPos(rEndPos),
162 0 : mnSteps(nSteps)
163 : {
164 0 : }
165 :
166 : protected:
167 :
168 : virtual void execute() SAL_OVERRIDE;
169 :
170 : private:
171 : glm::vec3 maStartPos;
172 : glm::vec3 maEndPos;
173 : sal_Int32 mnSteps;
174 :
175 : };
176 :
177 0 : void RenderAnimationThread::execute()
178 : {
179 0 : osl::MutexGuard aGuard(mpChart->maMutex);
180 0 : glm::vec3 aStep = (maEndPos - maStartPos)/(float)mnSteps;
181 0 : for(sal_Int32 i = 0; i < mnSteps; ++i)
182 : {
183 0 : mpChart->maCameraPosition += aStep;
184 0 : mpChart->mpCamera->setPosition(mpChart->maCameraPosition);
185 : /*
186 : mpChart->maCameraDirection += mpChart->maStepDirection;
187 : mpChart->mpCamera->setDirection(mpChart->maCameraDirection);
188 : */
189 0 : renderFrame();
190 : }
191 0 : mpChart->mpRenderer->ReleaseScreenTextShapes();
192 0 : }
193 :
194 0 : class RenderBenchMarkThread : public RenderThread
195 : {
196 : public:
197 0 : explicit RenderBenchMarkThread(GL3DBarChart * pChart)
198 : : RenderThread(pChart)
199 : , mbAutoFlyExecuting(false)
200 : , mbExecuting(false)
201 : , mbNeedFlyBack(false)
202 : , mnStep(0)
203 0 : , mnStepsTotal(0)
204 : {
205 0 : osl_getSystemTime(&maClickFlyBackStartTime);
206 0 : osl_getSystemTime(&maClickFlyBackEndTime);
207 0 : }
208 : protected:
209 : virtual void execute() SAL_OVERRIDE;
210 : private:
211 : void ProcessMouseEvent();
212 : void MoveCamera();
213 : void MoveCameraToBar();
214 : void MoveToBar();
215 : void MoveToSelectedBar();
216 : void MoveToDefault();
217 : void MoveToCorner();
218 : void ProcessScroll();
219 : void UpdateScreenText();
220 : void ProcessClickFlyBack();
221 : void AutoMoveToBar();
222 : private:
223 : glm::vec3 maStartPos;
224 : glm::vec3 maEndPos;
225 : bool mbAutoFlyExecuting;
226 : bool mbExecuting;
227 : bool mbNeedFlyBack;
228 : glm::vec3 maStep;
229 : glm::vec3 maStepDirection;
230 : glm::mat4 maMatrixStep;
231 : size_t mnStep;
232 : size_t mnStepsTotal;
233 : TimeValue maClickFlyBackStartTime;
234 : TimeValue maClickFlyBackEndTime;
235 : glm::vec3 maTargetPosition;
236 : glm::vec3 maTargetDirection;
237 : };
238 :
239 0 : void RenderBenchMarkThread::MoveCamera()
240 : {
241 0 : if(mnStep < mnStepsTotal)
242 : {
243 0 : ++mnStep;
244 0 : mpChart->maCameraPosition += maStep;
245 0 : mpChart->mpCamera->setPosition(mpChart->maCameraPosition);
246 0 : mpChart->maCameraDirection += maStepDirection;
247 0 : mpChart->mpCamera->setDirection(mpChart->maCameraDirection);
248 : }
249 : else
250 : {
251 0 : mnStep = 0;
252 0 : mbExecuting = false;
253 0 : mbAutoFlyExecuting = false;
254 0 : mbNeedFlyBack = false;
255 0 : mpChart->maRenderEvent = EVENT_NONE;
256 : }
257 0 : }
258 :
259 0 : void RenderBenchMarkThread::MoveCameraToBar()
260 : {
261 0 : if(mnStep < mnStepsTotal)
262 : {
263 0 : ++mnStep;
264 0 : mpChart->mpRenderer->AddMatrixDiff(maMatrixStep);
265 : }
266 : else
267 : {
268 0 : mpChart->maCameraPosition = maTargetPosition;
269 0 : mpChart->maCameraDirection = maTargetDirection;
270 0 : mpChart->mpCamera->setPosition(maTargetPosition);
271 0 : mpChart->mpCamera->setDirection(maTargetDirection);
272 0 : mpChart->mpRenderer->ResetMatrixDiff();
273 0 : mnStep = 0;
274 0 : mbExecuting = false;
275 0 : mbAutoFlyExecuting = false;
276 0 : mbNeedFlyBack = true;
277 0 : osl_getSystemTime(&maClickFlyBackStartTime);
278 0 : osl_getSystemTime(&maClickFlyBackEndTime);
279 0 : mpChart->maRenderEvent = EVENT_SHOW_SELECT;
280 : }
281 0 : }
282 :
283 :
284 0 : void RenderBenchMarkThread::MoveToDefault()
285 : {
286 0 : if ((mpChart->maCameraPosition == mpChart->maDefaultCameraDirection) &&
287 0 : (mpChart->maCameraDirection == mpChart->maDefaultCameraDirection))
288 : {
289 0 : mnStep = 0;
290 0 : mbExecuting = false;
291 0 : mpChart->maRenderEvent = EVENT_NONE;
292 0 : return;
293 : }
294 0 : if (!mbExecuting)
295 : {
296 0 : mpChart->mpRenderer->EndClick();
297 0 : mnStep = 0;
298 0 : mnStepsTotal = STEPS;
299 0 : maStep = (mpChart->maDefaultCameraPosition - mpChart->maCameraPosition)/((float)mnStepsTotal);
300 0 : maStepDirection = (mpChart->maDefaultCameraDirection - mpChart->maCameraDirection)/((float)mnStepsTotal);
301 0 : mbExecuting = true;
302 : }
303 0 : MoveCamera();
304 : }
305 :
306 0 : void RenderBenchMarkThread::MoveToBar()
307 : {
308 0 : if (!mbExecuting)
309 : {
310 0 : mpChart->mnSelectBarId = mpChart->barIdAtPosition(mpChart->maClickPos);
311 :
312 0 : std::map<sal_uInt32, const GL3DBarChart::BarInformation>::const_iterator itr = mpChart->maBarMap.find(mpChart->mnSelectBarId);
313 0 : if(itr == mpChart->maBarMap.end())
314 : {
315 0 : mpChart->mnSelectBarId = mpChart->mnPreSelectBarId;
316 0 : mpChart->maRenderEvent = mpChart->maPreRenderEvent;
317 0 : mpChart->maClickCond.set();
318 0 : return;
319 : }
320 0 : mpChart->mpRenderer->EndClick();
321 0 : const GL3DBarChart::BarInformation& rBarInfo = itr->second;
322 0 : mnStep = 0;
323 0 : mnStepsTotal = STEPS;
324 0 : maTargetPosition = rBarInfo.maPos;
325 0 : maTargetPosition.z += 240;
326 0 : maTargetPosition.x += BAR_SIZE_X / 2.0f;
327 0 : maTargetDirection = rBarInfo.maPos;
328 0 : maTargetDirection.x += BAR_SIZE_X / 2.0f;
329 0 : maTargetDirection.y += BAR_SIZE_Y / 2.0f;
330 0 : maTargetPosition.y = maTargetDirection.y - 240;
331 0 : maMatrixStep = mpChart->mpRenderer->GetDiffOfTwoCameras(mpChart->maCameraPosition, maTargetPosition, mpChart->maCameraDirection, maTargetDirection)/((float)mnStepsTotal);
332 0 : mpChart->maClickCond.set();
333 0 : mbExecuting = true;
334 0 : mbNeedFlyBack = false;
335 0 : mpChart->mpRenderer->StartClick(mpChart->mnSelectBarId);
336 : }
337 0 : MoveCameraToBar();
338 : }
339 :
340 0 : void RenderBenchMarkThread::MoveToSelectedBar()
341 : {
342 0 : mpChart->mnSelectBarId = mpChart->mnUpdateBarId;
343 0 : std::map<sal_uInt32, const GL3DBarChart::BarInformation>::const_iterator itr = mpChart->maBarMap.find(mpChart->mnSelectBarId);
344 0 : if(itr == mpChart->maBarMap.end())
345 : {
346 0 : mpChart->mnSelectBarId = mpChart->mnPreSelectBarId;
347 0 : mpChart->maRenderEvent = mpChart->maPreRenderEvent;
348 0 : mpChart->maClickCond.set();
349 0 : return;
350 : }
351 0 : mpChart->mpRenderer->EndClick();
352 0 : const GL3DBarChart::BarInformation& rBarInfo = itr->second;
353 0 : mnStep = 0;
354 0 : mnStepsTotal = STEPS_UPDATE;
355 0 : maTargetPosition = rBarInfo.maPos;
356 0 : maTargetPosition.z += 240;
357 0 : maTargetPosition.x += BAR_SIZE_X / 2.0f;
358 0 : maTargetDirection = rBarInfo.maPos;
359 0 : maTargetDirection.x += BAR_SIZE_X / 2.0f;
360 0 : maTargetDirection.y += BAR_SIZE_Y / 2.0f;
361 0 : maTargetPosition.y = maTargetDirection.y - 240;
362 0 : maMatrixStep = mpChart->mpRenderer->GetDiffOfTwoCameras( maTargetPosition, maTargetDirection)/((float)mnStepsTotal);
363 0 : mpChart->maClickCond.set();
364 0 : mbExecuting = true;
365 0 : mbNeedFlyBack = false;
366 0 : mpChart->mpRenderer->StartClick(mpChart->mnSelectBarId);
367 0 : mpChart->maRenderEvent = EVENT_CLICK;
368 : }
369 :
370 0 : void RenderBenchMarkThread::AutoMoveToBar()
371 : {
372 0 : if (!mbAutoFlyExecuting)
373 : {
374 0 : mpChart->mpRenderer->EndClick();
375 0 : std::map<sal_uInt32, const GL3DBarChart::BarInformation>::const_iterator itr = mpChart->maBarMap.find(mpChart->mnSelectBarId);
376 0 : if(itr == mpChart->maBarMap.end())
377 : {
378 0 : mpChart->maRenderEvent = EVENT_NONE;
379 0 : return;
380 : }
381 0 : const GL3DBarChart::BarInformation& rBarInfo = itr->second;
382 0 : mnStep = 0;
383 0 : mnStepsTotal = STEPS;
384 0 : maTargetPosition = rBarInfo.maPos;
385 0 : maTargetPosition.z += 240;
386 0 : maTargetPosition.x += BAR_SIZE_X / 2.0f;
387 0 : maTargetDirection = rBarInfo.maPos;
388 0 : maTargetDirection.x += BAR_SIZE_X / 2.0f;
389 0 : maTargetDirection.y += BAR_SIZE_Y / 2.0f;
390 0 : maTargetPosition.y = maTargetDirection.y - 240;
391 0 : maMatrixStep = mpChart->mpRenderer->GetDiffOfTwoCameras(mpChart->maCameraPosition, maTargetPosition, mpChart->maCameraDirection, maTargetDirection)/((float)mnStepsTotal);
392 0 : mpChart->mpRenderer->StartClick(mpChart->mnSelectBarId);
393 0 : mbAutoFlyExecuting = true;
394 0 : mbNeedFlyBack = false;
395 : }
396 0 : MoveCameraToBar();
397 : }
398 :
399 0 : void RenderBenchMarkThread::MoveToCorner()
400 : {
401 0 : if (!mbExecuting)
402 : {
403 0 : mpChart->mpRenderer->EndClick();
404 0 : mnStep = 0;
405 0 : mnStepsTotal = STEPS;
406 0 : maStep = (mpChart->getCornerPosition(mpChart->mnCornerId) - mpChart->maCameraPosition) / float(mnStepsTotal);
407 0 : maStepDirection = (glm::vec3(mpChart->mnMaxX/2.0f, mpChart->mnMaxY/2.0f, 0) - mpChart->maCameraDirection)/ float(mnStepsTotal);
408 0 : mbExecuting = true;
409 : }
410 0 : MoveCamera();
411 0 : }
412 :
413 0 : void RenderBenchMarkThread::ProcessScroll()
414 : {
415 : //will add other process later
416 0 : mpChart->mpRenderer->EndClick();
417 0 : mnStep = 0;
418 0 : mnStepsTotal = STEPS;
419 0 : mpChart->maRenderEvent = EVENT_SHOW_SCROLL;
420 0 : }
421 :
422 0 : void RenderBenchMarkThread::ProcessClickFlyBack()
423 : {
424 0 : if (!mbNeedFlyBack)
425 0 : return;
426 0 : osl_getSystemTime(&maClickFlyBackEndTime);
427 0 : int nDeltaMs = GL3DBarChart::calcTimeInterval(maClickFlyBackStartTime, maClickFlyBackEndTime);
428 0 : if(nDeltaMs >= 10000)
429 : {
430 0 : mpChart->maRenderEvent = EVENT_MOVE_TO_DEFAULT;
431 : }
432 : }
433 :
434 0 : void RenderBenchMarkThread::ProcessMouseEvent()
435 : {
436 0 : ProcessClickFlyBack();
437 0 : if (mpChart->maRenderEvent == EVENT_SELECTBAR_UPDEDATE)
438 : {
439 0 : MoveToSelectedBar();
440 : }
441 0 : else if (mpChart->maRenderEvent == EVENT_CLICK)
442 : {
443 0 : MoveToBar();
444 : }
445 0 : else if (mpChart->maRenderEvent == EVENT_MOVE_TO_DEFAULT)
446 : {
447 0 : MoveToDefault();
448 : }
449 0 : else if ((mpChart->maRenderEvent == EVENT_DRAG_LEFT) || (mpChart->maRenderEvent == EVENT_DRAG_RIGHT))
450 : {
451 0 : MoveToCorner();
452 : }
453 0 : else if (mpChart->maRenderEvent == EVENT_SCROLL)
454 : {
455 0 : ProcessScroll();
456 : }
457 0 : else if (mpChart->maRenderEvent == EVENT_AUTO_FLY)
458 : {
459 0 : AutoMoveToBar();
460 : }
461 :
462 0 : }
463 :
464 0 : void RenderBenchMarkThread::UpdateScreenText()
465 : {
466 0 : if (mpChart->mbScreenTextNewRender)
467 : {
468 0 : mpChart->mpWindow->getContext().makeCurrent();
469 0 : mpChart->mpRenderer->ReleaseScreenTextTexture();
470 0 : for(boost::ptr_vector<opengl3D::Renderable3DObject>::iterator itr = mpChart->maScreenTextShapes.begin(),
471 0 : itrEnd = mpChart->maScreenTextShapes.end(); itr != itrEnd; ++itr)
472 : {
473 0 : itr->render();
474 : }
475 0 : mpChart->mbScreenTextNewRender = false;
476 0 : mpChart->mpWindow->getContext().resetCurrent();
477 : }
478 0 : }
479 :
480 0 : void RenderBenchMarkThread::execute()
481 : {
482 : while (true)
483 : {
484 : {
485 0 : osl::MutexGuard aGuard(mpChart->maMutex);
486 0 : mpChart->maCond2.reset();
487 0 : if (mpChart->mbRenderDie)
488 0 : break;
489 0 : UpdateScreenText();
490 0 : ProcessMouseEvent();
491 0 : renderFrame();
492 0 : mpChart->miFrameCount++;
493 : }
494 0 : if (mpChart->maCond1.check())
495 : {
496 0 : mpChart->maCond1.reset();
497 0 : mpChart->maCond2.wait();
498 : }
499 0 : }
500 0 : }
501 :
502 0 : GL3DBarChart::GL3DBarChart(
503 : const css::uno::Reference<css::chart2::XChartType>& xChartType,
504 : OpenGLWindow* pWindow) :
505 : mxChartType(xChartType),
506 0 : mpRenderer(new opengl3D::OpenGL3DRenderer()),
507 : mpWindow(pWindow),
508 : mpCamera(NULL),
509 : mbValidContext(true),
510 0 : mpTextCache(new opengl3D::TextCache()),
511 : mnMaxX(0),
512 : mnMaxY(0),
513 : mnDistance(0.0),
514 : mnCornerId(0),
515 : mbNeedsNewRender(true),
516 : mbCameraInit(false),
517 : mbRenderDie(false),
518 : maRenderEvent(EVENT_NONE),
519 : maPreRenderEvent(EVENT_NONE),
520 : mnSelectBarId(0),
521 : mnPreSelectBarId(0),
522 : miScrollRate(0),
523 : mbScrollFlg(false),
524 : mbScreenTextNewRender(false),
525 : maFPS(OUString("Render FPS: 0")),
526 : maDataUpdateFPS(OUString("Data Update FPS: 0")),
527 : miFrameCount(0),
528 : miDataUpdateCounter(0),
529 : mnColorRate(0),
530 : mbBenchMarkMode(false),
531 : mnHistoryCounter(0),
532 : mnBarsInRow(0),
533 : mbAutoFly(false),
534 0 : mnUpdateBarId(0)
535 : {
536 0 : maFPSRenderStartTime.Seconds = maFPSRenderStartTime.Nanosec = 0;
537 0 : maFPSRenderEndTime.Seconds = maFPSRenderEndTime.Nanosec = 0;
538 0 : maDataUpdateStartTime.Seconds = maDataUpdateStartTime.Nanosec = 0;
539 0 : maDataUpdateEndTime.Seconds = maDataUpdateEndTime.Nanosec = 0;
540 :
541 0 : static const char *aBenchMark = getenv("UNLOCK_FPS_MODE");
542 0 : if (aBenchMark)
543 : {
544 0 : mbBenchMarkMode = atoi(aBenchMark);
545 : }
546 0 : if (mbBenchMarkMode)
547 : {
548 0 : static const char *scrollFrame = getenv("SCROLL_RATE");
549 0 : if (scrollFrame)
550 : {
551 0 : miScrollRate = atoi(scrollFrame);
552 0 : if (miScrollRate > 0)
553 : {
554 0 : mbScrollFlg = true;
555 0 : mpRenderer->SetScroll();
556 : }
557 : }
558 0 : char *aAutoFly = getenv("AUTO_FLY");
559 0 : if (aAutoFly)
560 : {
561 0 : mbAutoFly = atoi(aAutoFly);
562 : }
563 0 : maIdle.SetPriority(SchedulerPriority::REPAINT);
564 0 : maIdle.SetIdleHdl(LINK(this, GL3DBarChart, UpdateTimerHdl));
565 0 : maIdle.Start();
566 0 : osl_getSystemTime(&maFPSRenderStartTime);
567 0 : osl_getSystemTime(&maFPSRenderEndTime);
568 0 : osl_getSystemTime(&maDataUpdateStartTime);
569 0 : osl_getSystemTime(&maDataUpdateEndTime);
570 : }
571 0 : Size aSize = mpWindow->GetSizePixel();
572 0 : mpRenderer->SetSize(aSize);
573 0 : mpWindow->setRenderer(this);
574 0 : mpWindow->getContext().makeCurrent();
575 0 : mpRenderer->init();
576 0 : mpWindow->getContext().resetCurrent();
577 0 : }
578 :
579 0 : GL3DBarChart::BarInformation::BarInformation(const glm::vec3& rPos, float nVal,
580 : sal_Int32 nIndex, sal_Int32 nSeriesIndex):
581 : maPos(rPos),
582 : mnVal(nVal),
583 : mnIndex(nIndex),
584 0 : mnSeriesIndex(nSeriesIndex)
585 : {
586 0 : }
587 :
588 0 : GL3DBarChart::~GL3DBarChart()
589 : {
590 0 : if (mbBenchMarkMode)
591 : {
592 0 : SharedResourceAccess aResGuard(maCond1, maCond2);
593 0 : osl::MutexGuard aGuard(maMutex);
594 0 : mbRenderDie = true;
595 : }
596 :
597 0 : joinRenderThread();
598 :
599 0 : if(mbValidContext)
600 0 : mpWindow->setRenderer(NULL);
601 0 : }
602 :
603 0 : void GL3DBarChart::create3DShapes(const boost::ptr_vector<VDataSeries>& rDataSeriesContainer,
604 : ExplicitCategoriesProvider& rCatProvider)
605 : {
606 0 : SharedResourceAccess aResGuard(maCond1, maCond2);
607 0 : osl::MutexGuard aGuard(maMutex);
608 0 : if(mnSelectBarId)
609 : {
610 0 : int nSelectBarId = mnSelectBarId;
611 0 : int nPreSelectBarId = nSelectBarId;
612 0 : nSelectBarId -= 10;
613 0 : sal_uInt32 nSelectRow = (nSelectBarId - SHAPE_START_ID) / ID_STEP / (mnBarsInRow + 1);
614 0 : sal_uInt32 nPreSelectRow = (nPreSelectBarId - SHAPE_START_ID) / ID_STEP / (mnBarsInRow + 1);
615 0 : if(nSelectRow == nPreSelectRow)
616 : {
617 0 : std::map<sal_uInt32, const GL3DBarChart::BarInformation>::const_iterator itr = maBarMap.find(nSelectBarId);
618 0 : if((maRenderEvent == EVENT_CLICK || maRenderEvent == EVENT_SHOW_SELECT || maRenderEvent == EVENT_AUTO_FLY)&&(itr != maBarMap.end()))
619 : {
620 0 : mnUpdateBarId = nSelectBarId;
621 0 : maRenderEvent = EVENT_SELECTBAR_UPDEDATE;
622 : }
623 : }
624 : }
625 0 : mpRenderer->ReleaseShapes();
626 : // Each series of data flows from left to right, and multiple series are
627 : // stacked vertically along y axis.
628 :
629 0 : sal_uInt32 nId = SHAPE_START_ID;
630 0 : float nXEnd = 0.0;
631 0 : float nYPos = 0.0;
632 :
633 : const Color aSeriesColor[] = {
634 : COL_RED, COL_GREEN, COL_YELLOW, COL_BROWN, COL_BLUE
635 0 : };
636 :
637 0 : maCategories.clear();
638 0 : maSeriesNames.clear();
639 0 : maSeriesNames.reserve(rDataSeriesContainer.size());
640 0 : maBarMap.clear();
641 0 : maShapes.clear();
642 0 : if (mbBenchMarkMode)
643 : {
644 0 : mnColorRate = 0;
645 : }
646 0 : maShapes.push_back(new opengl3D::Camera(mpRenderer.get()));
647 0 : mpCamera = static_cast<opengl3D::Camera*>(&maShapes.back());
648 :
649 0 : sal_Int32 nSeriesIndex = 0;
650 0 : sal_Int32 nMaxPointCount = 0;
651 0 : double nMaxVal = findMaxValue(rDataSeriesContainer)/100;
652 0 : if (rDataSeriesContainer.empty())
653 : {
654 0 : mnBarsInRow = 0;
655 : }
656 : else
657 : {
658 0 : const VDataSeries& rFirstRow = *(rDataSeriesContainer.begin());
659 0 : mnBarsInRow = rFirstRow.getTotalPointCount();
660 : }
661 0 : for (boost::ptr_vector<VDataSeries>::const_iterator itr = rDataSeriesContainer.begin(),
662 0 : itrEnd = rDataSeriesContainer.end(); itr != itrEnd; ++itr)
663 : {
664 0 : nYPos = nSeriesIndex * (BAR_SIZE_Y + BAR_DISTANCE_Y) + BAR_DISTANCE_Y;
665 :
666 0 : const VDataSeries& rDataSeries = *itr;
667 0 : sal_Int32 nPointCount = rDataSeries.getTotalPointCount();
668 0 : nMaxPointCount = std::max(nMaxPointCount, nPointCount);
669 :
670 0 : bool bMappedFillProperty = rDataSeries.hasPropertyMapping("FillColor");
671 :
672 : // Create series name text object.
673 : OUString aSeriesName =
674 : DataSeriesHelper::getDataSeriesLabel(
675 0 : rDataSeries.getModel(), mxChartType->getRoleOfSequenceForSeriesLabel());
676 :
677 0 : maSeriesNames.push_back(aSeriesName);
678 :
679 0 : if(!aSeriesName.isEmpty())
680 : {
681 0 : maShapes.push_back(new opengl3D::Text(mpRenderer.get(),
682 0 : *mpTextCache, aSeriesName, nId));
683 0 : nId += ID_STEP;
684 0 : opengl3D::Text* p = static_cast<opengl3D::Text*>(&maShapes.back());
685 0 : glm::vec3 aTopLeft, aTopRight, aBottomRight;
686 0 : aTopRight.x = -BAR_DISTANCE_Y;
687 0 : aTopRight.y = nYPos + BAR_DISTANCE_Y;
688 0 : aTopLeft.x = calculateTextWidth(aSeriesName) * -1.0 - BAR_DISTANCE_Y;
689 0 : aTopLeft.y = nYPos + BAR_DISTANCE_Y;
690 0 : aBottomRight = aTopRight;
691 0 : aBottomRight.y -= TEXT_HEIGHT;
692 0 : p->setPosition(aTopLeft, aTopRight, aBottomRight);
693 : }
694 :
695 0 : sal_Int32 nColor = aSeriesColor[nSeriesIndex % SAL_N_ELEMENTS(aSeriesColor)].GetColor();
696 0 : for(sal_Int32 nIndex = 0; nIndex < nPointCount; ++nIndex)
697 : {
698 0 : if(bMappedFillProperty)
699 : {
700 0 : double nPropVal = rDataSeries.getValueByProperty(nIndex, "FillColor");
701 0 : if(!rtl::math::isNan(nPropVal))
702 0 : nColor = static_cast<sal_uInt32>(nPropVal);
703 : }
704 :
705 0 : float nVal = rDataSeries.getYValue(nIndex);
706 0 : if (rtl::math::isNan(nVal))
707 0 : continue;
708 :
709 0 : float nXPos = nIndex * (BAR_SIZE_X + BAR_DISTANCE_X) + BAR_DISTANCE_X;
710 :
711 0 : glm::mat4 aScaleMatrix = glm::scale(glm::vec3(BAR_SIZE_X, BAR_SIZE_Y, float(nVal/nMaxVal)));
712 0 : glm::mat4 aTranslationMatrix = glm::translate(glm::vec3(nXPos, nYPos, 0.0f));
713 0 : glm::mat4 aBarPosition = aTranslationMatrix * aScaleMatrix;
714 :
715 : maBarMap.insert(std::pair<sal_uInt32, BarInformation>(nId,
716 0 : BarInformation(glm::vec3(nXPos, nYPos, float(nVal/nMaxVal)),
717 0 : nVal, nIndex, nSeriesIndex)));
718 0 : recordBarHistory(nId, nVal);
719 0 : if (mbBenchMarkMode)
720 : {
721 0 : std::map<sal_uInt32, sal_uInt32>::const_iterator it = maBarColorMap.find(nId);
722 0 : if (it == maBarColorMap.end())
723 : {
724 0 : maBarColorMap[nId] = nColor;
725 : }
726 : else
727 : {
728 0 : if(mbAutoFly)
729 0 : processAutoFly(nId, nColor);
730 : }
731 : }
732 0 : maShapes.push_back(new opengl3D::Bar(mpRenderer.get(), aBarPosition, nColor, nId));
733 0 : nId += ID_STEP;
734 : }
735 :
736 0 : float nThisXEnd = nPointCount * (BAR_SIZE_X + BAR_DISTANCE_X);
737 0 : if (nXEnd < nThisXEnd)
738 0 : nXEnd = nThisXEnd;
739 :
740 0 : ++nSeriesIndex;
741 0 : }
742 :
743 0 : nYPos += BAR_SIZE_Y + BAR_DISTANCE_Y;
744 :
745 : // X axis
746 0 : maShapes.push_back(new opengl3D::Line(mpRenderer.get(), nId));
747 0 : nId += ID_STEP;
748 0 : opengl3D::Line* pAxis = static_cast<opengl3D::Line*>(&maShapes.back());
749 0 : glm::vec3 aBegin;
750 0 : aBegin.y = nYPos;
751 0 : glm::vec3 aEnd = aBegin;
752 0 : aEnd.x = mbBenchMarkMode ? (mbScrollFlg ? nXEnd - BAR_SIZE_X : nXEnd) : nXEnd;
753 0 : pAxis->setPosition(aBegin, aEnd);
754 0 : pAxis->setLineColor(COL_BLUE);
755 :
756 : // Y axis
757 0 : maShapes.push_back(new opengl3D::Line(mpRenderer.get(), nId));
758 0 : nId += ID_STEP;
759 0 : pAxis = static_cast<opengl3D::Line*>(&maShapes.back());
760 0 : aBegin.x = aBegin.y = 0;
761 0 : aEnd = aBegin;
762 0 : aEnd.y = nYPos;
763 0 : pAxis->setPosition(aBegin, aEnd);
764 0 : pAxis->setLineColor(COL_BLUE);
765 :
766 : // Chart background.
767 0 : maShapes.push_back(new opengl3D::Rectangle(mpRenderer.get(), nId));
768 0 : nId += ID_STEP;
769 0 : opengl3D::Rectangle* pRect = static_cast<opengl3D::Rectangle*>(&maShapes.back());
770 0 : glm::vec3 aTopLeft;
771 0 : glm::vec3 aTopRight = aTopLeft;
772 0 : aTopRight.x = mbBenchMarkMode ? (mbScrollFlg ? nXEnd - BAR_SIZE_X : nXEnd + 2 * BAR_DISTANCE_X) : (nXEnd + 2 * BAR_DISTANCE_X);
773 0 : glm::vec3 aBottomRight = aTopRight;
774 0 : aBottomRight.y = nYPos;
775 0 : pRect->setPosition(aTopLeft, aTopRight, aBottomRight);
776 0 : pRect->setFillColor(COL_BLACK);
777 0 : pRect->setLineColor(COL_BLUE);
778 0 : if (mbScrollFlg)
779 0 : mpRenderer->SetSceneEdge(BAR_DISTANCE_X - 0.001f, aTopRight.x - BAR_DISTANCE_X);
780 : else
781 0 : mpRenderer->SetSceneEdge(-0.001f, aTopRight.x);
782 : // Create category texts along X-axis at the bottom.
783 0 : uno::Sequence<OUString> aCats = rCatProvider.getSimpleCategories();
784 0 : for (sal_Int32 i = 0; i < aCats.getLength(); ++i)
785 : {
786 0 : if (mbBenchMarkMode && mbScrollFlg && (i + 1 == aCats.getLength()))
787 0 : break;
788 0 : maCategories.push_back(aCats[i]);
789 0 : if(aCats[i].isEmpty())
790 0 : continue;
791 :
792 0 : float nXPos = i * (BAR_SIZE_X + BAR_DISTANCE_X);
793 :
794 0 : maShapes.push_back(new opengl3D::Text(mpRenderer.get(), *mpTextCache,
795 0 : aCats[i], nId));
796 0 : nId += ID_STEP;
797 0 : opengl3D::Text* p = static_cast<opengl3D::Text*>(&maShapes.back());
798 0 : aTopLeft.x = nXPos + TEXT_HEIGHT + 0.5 * BAR_SIZE_X;
799 0 : aTopLeft.y = nYPos + calculateTextWidth(aCats[i]) + 0.5 * BAR_DISTANCE_Y;
800 0 : aTopRight = aTopLeft;
801 0 : aTopRight.y = nYPos + 0.5* BAR_DISTANCE_Y;
802 0 : aBottomRight.x = nXPos;
803 0 : aBottomRight.y = nYPos + 0.5 * BAR_DISTANCE_Y;
804 0 : p->setPosition(aTopLeft, aTopRight, aBottomRight);
805 :
806 : // create shapes on other side as well
807 :
808 0 : maShapes.push_back(new opengl3D::Text(mpRenderer.get(), *mpTextCache,
809 0 : aCats[i], nId));
810 0 : nId += ID_STEP;
811 0 : p = static_cast<opengl3D::Text*>(&maShapes.back());
812 0 : aTopLeft.x = nXPos + TEXT_HEIGHT + 0.5 * BAR_SIZE_X;
813 0 : aTopLeft.y = - 0.5 * BAR_DISTANCE_Y;
814 0 : aTopRight = aTopLeft;
815 0 : aTopRight.y = -calculateTextWidth(aCats[i]) - 0.5* BAR_DISTANCE_Y;
816 0 : aBottomRight.x = nXPos;
817 0 : aBottomRight.y = -calculateTextWidth(aCats[i]) - 0.5 * BAR_DISTANCE_Y;
818 0 : p->setPosition(aTopLeft, aTopRight, aBottomRight);
819 : }
820 :
821 0 : mnMaxX = nMaxPointCount * (BAR_SIZE_X + BAR_DISTANCE_X) + 40;
822 0 : mnMaxY = nSeriesIndex * (BAR_SIZE_Y + BAR_DISTANCE_Y) + 40;
823 0 : if (!mbCameraInit)
824 : {
825 0 : mnDistance = sqrt(mnMaxX * mnMaxX + mnMaxY * mnMaxY + DEFAULT_CAMERA_HEIGHT * DEFAULT_CAMERA_HEIGHT);
826 0 : maDefaultCameraDirection = glm::vec3(mnMaxX * 0.4, mnMaxY * 0.35, 0);
827 0 : maDefaultCameraPosition = glm::vec3(maDefaultCameraDirection.x, maDefaultCameraDirection.y - mnDistance, DEFAULT_CAMERA_HEIGHT * 2);
828 0 : mnCornerId = 0;
829 0 : mbCameraInit = true;
830 0 : float pi = 3.1415926f;
831 0 : float nAngleX = -pi / 6.5f;
832 0 : float nAngleZ = -pi / 8.0f;
833 0 : glm::mat4 aDefaultRotateMatrix = glm::eulerAngleYXZ(0.0f, nAngleX, nAngleZ);
834 0 : maDefaultCameraPosition = glm::vec3(aDefaultRotateMatrix * glm::vec4(maDefaultCameraPosition, 1.0f));
835 0 : maCameraPosition = maDefaultCameraPosition;
836 0 : maCameraDirection = maDefaultCameraDirection;
837 0 : mpCamera->setPosition(maCameraPosition);
838 0 : mpCamera->setDirection(maCameraDirection);
839 : }
840 : else
841 : {
842 0 : mpCamera->setPosition(maCameraPosition);
843 0 : mpCamera->setDirection(maCameraDirection);
844 : }
845 0 : if (mbBenchMarkMode && (!mpRenderThread.is()))
846 : {
847 : //if scroll the bars, set the speed and distance first
848 0 : if (mbScrollFlg)
849 : {
850 0 : mpRenderer->SetScrollSpeed((float)(BAR_SIZE_X + BAR_DISTANCE_X) / (float)miScrollRate);
851 0 : mpRenderer->SetScrollDistance((float)(BAR_SIZE_X + BAR_DISTANCE_X));
852 : }
853 0 : spawnRenderThread(new RenderBenchMarkThread(this));
854 : }
855 0 : miDataUpdateCounter++;
856 0 : mnHistoryCounter++;
857 0 : mbNeedsNewRender = true;
858 0 : }
859 :
860 0 : void GL3DBarChart::joinRenderThread()
861 : {
862 0 : if(mpRenderThread.is())
863 : {
864 : // FIXME: badly want to assert that we don't
865 : // hold the mutex here ... but can't API-wise.
866 0 : mpRenderThread->join();
867 : }
868 0 : }
869 :
870 0 : void GL3DBarChart::spawnRenderThread(RenderThread *pThread)
871 : {
872 0 : joinRenderThread(); // not holding maMutex
873 :
874 0 : osl::MutexGuard aGuard(maMutex);
875 :
876 0 : Size aSize = mpWindow->GetSizePixel();
877 0 : mpWindow->getContext().setWinSize(aSize);
878 0 : mpRenderThread = rtl::Reference<RenderThread>(pThread);
879 0 : mpWindow->getContext().resetCurrent();
880 0 : mpRenderThread->launch();
881 0 : }
882 :
883 0 : void GL3DBarChart::update()
884 : {
885 0 : if (mbBenchMarkMode)
886 0 : return;
887 0 : spawnRenderThread(new RenderOneFrameThread(this));
888 : }
889 :
890 0 : void GL3DBarChart::moveToDefault()
891 : {
892 0 : if(mbBenchMarkMode)
893 : {
894 : // add correct handling here!!
895 0 : if ((maRenderEvent != EVENT_NONE) && (maRenderEvent != EVENT_SHOW_SCROLL) &&
896 0 : (maRenderEvent != EVENT_AUTO_FLY) && (maRenderEvent != EVENT_SHOW_SELECT))
897 0 : return;
898 :
899 : {
900 0 : SharedResourceAccess aResGuard(maCond1, maCond2);
901 0 : osl::MutexGuard aGuard(maMutex);
902 0 : maRenderEvent = EVENT_MOVE_TO_DEFAULT;
903 : }
904 0 : return;
905 : }
906 :
907 0 : spawnRenderThread(new RenderAnimationThread(this, maCameraPosition, maDefaultCameraPosition, STEPS));
908 :
909 : /*
910 : * TODO: moggi: add to thread
911 : glm::vec3 maTargetDirection = maDefaultCameraDirection;
912 : maStepDirection = (maTargetDirection - maCameraDirection)/((float)mnStepsTotal);
913 : */
914 : }
915 :
916 0 : sal_uInt32 GL3DBarChart::barIdAtPosition(const Point& rPos)
917 : {
918 0 : sal_uInt32 nId = 5;
919 : {
920 0 : osl::MutexGuard aGuard(maMutex);
921 0 : mpWindow->getContext().makeCurrent();
922 0 : mpRenderer->SetPickingMode(true);
923 0 : renderFrame();
924 0 : nId = mpRenderer->GetPixelColorFromPoint(rPos.X(), rPos.Y());
925 0 : mpRenderer->SetPickingMode(false);
926 0 : mpWindow->getContext().resetCurrent();
927 : }
928 0 : return nId;
929 : }
930 :
931 0 : void GL3DBarChart::clickedAt(const Point& rPos, sal_uInt16 nButtons)
932 : {
933 0 : if (nButtons == MOUSE_RIGHT)
934 : {
935 0 : moveToDefault();
936 0 : return;
937 : }
938 :
939 0 : if(nButtons != MOUSE_LEFT)
940 0 : return;
941 :
942 0 : if (mbBenchMarkMode)
943 : {
944 : // add correct handling here !!
945 0 : if ((maRenderEvent != EVENT_NONE) && (maRenderEvent != EVENT_SHOW_SCROLL) &&
946 0 : (maRenderEvent != EVENT_AUTO_FLY) && (maRenderEvent != EVENT_SHOW_SELECT))
947 0 : return;
948 :
949 : {
950 0 : SharedResourceAccess aResGuard(maCond1, maCond2);
951 0 : osl::MutexGuard aGuard(maMutex);
952 0 : maClickPos = rPos;
953 0 : mnPreSelectBarId = mnSelectBarId;
954 0 : maPreRenderEvent = maRenderEvent;
955 0 : maRenderEvent = EVENT_CLICK;
956 0 : maClickCond.reset();
957 : }
958 0 : maClickCond.wait();
959 0 : return;
960 : }
961 :
962 0 : sal_uInt32 nId = barIdAtPosition(rPos);
963 :
964 : std::map<sal_uInt32, const BarInformation>::const_iterator itr =
965 0 : maBarMap.find(nId);
966 :
967 0 : if(itr == maBarMap.end())
968 0 : return;
969 :
970 0 : const BarInformation& rBarInfo = itr->second;
971 :
972 : {
973 0 : osl::MutexGuard aGuard(maMutex);
974 0 : mpWindow->getContext().makeCurrent();
975 0 : glm::vec3 aTextPos = glm::vec3(rBarInfo.maPos.x + BAR_SIZE_X / 2.0f,
976 0 : rBarInfo.maPos.y + BAR_SIZE_Y / 2.0f,
977 0 : rBarInfo.maPos.z);
978 0 : maShapes.push_back(new opengl3D::ScreenText(mpRenderer.get(), *mpTextCache,
979 0 : "Value: " + OUString::number(rBarInfo.mnVal), glm::vec4(0.0f, 0.0f, 1.0f, 1.0f), CALC_POS_EVENT_ID));
980 0 : opengl3D::ScreenText* pScreenText = static_cast<opengl3D::ScreenText*>(&maShapes.back());
981 0 : pScreenText->setPosition(glm::vec2(-0.9f, 0.9f), glm::vec2(-0.6f, 0.8f), aTextPos);
982 0 : pScreenText->render();
983 0 : mpWindow->getContext().resetCurrent();
984 : }
985 :
986 0 : glm::vec3 aTargetPosition = rBarInfo.maPos;
987 0 : aTargetPosition.z += 240;
988 0 : aTargetPosition.y += BAR_SIZE_Y / 2.0f;
989 :
990 : spawnRenderThread(new RenderAnimationThread(this, maCameraPosition,
991 0 : aTargetPosition, STEPS));
992 :
993 : /*
994 : * TODO: moggi: add to thread
995 : glm::vec3 maTargetDirection = rBarInfo.maPos;
996 : maTargetDirection.x += BAR_SIZE_X / 2.0f;
997 : maTargetDirection.y += BAR_SIZE_Y / 2.0f;
998 :
999 : maStepDirection = (maTargetDirection - maCameraDirection)/((float)mnStepsTotal);
1000 : */
1001 : }
1002 :
1003 0 : void GL3DBarChart::render()
1004 : {
1005 0 : if (mbBenchMarkMode)
1006 0 : return;
1007 :
1008 0 : update();
1009 : }
1010 :
1011 0 : void GL3DBarChart::renderFrame()
1012 : {
1013 0 : Size aSize = mpWindow->GetSizePixel();
1014 0 : mpRenderer->SetSize(aSize);
1015 0 : if(mbNeedsNewRender)
1016 : {
1017 0 : mpRenderer->ReleaseTextTexture();
1018 0 : for(boost::ptr_vector<opengl3D::Renderable3DObject>::iterator itr = maShapes.begin(),
1019 0 : itrEnd = maShapes.end(); itr != itrEnd; ++itr)
1020 : {
1021 0 : itr->render();
1022 : }
1023 : }
1024 : else
1025 : {
1026 0 : mpCamera->render();
1027 : }
1028 0 : mpRenderer->ProcessUnrenderedShape(mbNeedsNewRender);
1029 0 : mbNeedsNewRender = false;
1030 0 : }
1031 :
1032 0 : void GL3DBarChart::mouseDragMove(const Point& rStartPos, const Point& rEndPos, sal_uInt16 )
1033 : {
1034 0 : long nDirection = rEndPos.X() - rStartPos.X();
1035 0 : SharedResourceAccess aResGuard(maCond1, maCond2);
1036 0 : osl::ClearableGuard<osl::Mutex> aGuard(maMutex);
1037 0 : if ((maRenderEvent == EVENT_NONE) || (maRenderEvent == EVENT_SHOW_SCROLL) ||
1038 0 : (maRenderEvent == EVENT_AUTO_FLY) || (maRenderEvent == EVENT_SHOW_SELECT))
1039 0 : maRenderEvent = nDirection > 0 ? EVENT_DRAG_RIGHT : EVENT_DRAG_LEFT;
1040 0 : bool bMove = false;
1041 0 : if(nDirection < 0)
1042 : {
1043 0 : mnCornerId = (mnCornerId + 1) % 4;
1044 0 : bMove = true;
1045 : }
1046 0 : else if(nDirection > 0)
1047 : {
1048 0 : mnCornerId = mnCornerId - 1;
1049 0 : if(mnCornerId < 0)
1050 0 : mnCornerId = 3;
1051 0 : bMove = true;
1052 : }
1053 :
1054 0 : if (bMove)
1055 : {
1056 0 : aGuard.clear();
1057 0 : moveToCorner();
1058 0 : }
1059 0 : }
1060 :
1061 0 : glm::vec3 GL3DBarChart::getCornerPosition(sal_Int8 nId)
1062 : {
1063 0 : float pi = 3.1415926f;
1064 0 : switch(nId)
1065 : {
1066 : case 0:
1067 : {
1068 0 : return glm::vec3(mnMaxX / 2 - mnDistance * sin(pi / 4), mnMaxY / 2 - mnDistance * cos(pi / 4), DEFAULT_CAMERA_HEIGHT * 2);
1069 : }
1070 : break;
1071 : case 1:
1072 : {
1073 0 : return glm::vec3(mnMaxX / 2 + mnDistance * sin(pi / 4), mnMaxY / 2 - mnDistance * cos(pi / 4), DEFAULT_CAMERA_HEIGHT * 2);
1074 : }
1075 : break;
1076 : case 2:
1077 : {
1078 0 : return glm::vec3(mnMaxX / 2 + mnDistance * sin(pi / 4), mnMaxY / 2 + mnDistance * cos(pi / 4), DEFAULT_CAMERA_HEIGHT * 2);
1079 : }
1080 : break;
1081 : case 3:
1082 : {
1083 0 : return glm::vec3(mnMaxX / 2 - mnDistance * sin(pi / 4), mnMaxY / 2 + mnDistance * cos(pi / 4), DEFAULT_CAMERA_HEIGHT * 2);
1084 : }
1085 : break;
1086 : default:
1087 : assert(false);
1088 : }
1089 0 : return maDefaultCameraPosition;
1090 : }
1091 :
1092 0 : void GL3DBarChart::moveToCorner()
1093 : {
1094 0 : if(mbBenchMarkMode)
1095 : {
1096 : // add correct handling here!!
1097 0 : return;
1098 : }
1099 :
1100 : spawnRenderThread(new RenderAnimationThread(this, maCameraPosition,
1101 0 : getCornerPosition(mnCornerId), STEPS));
1102 :
1103 : // TODO: moggi: add to thread
1104 : // maStepDirection = (glm::vec3(mnMaxX/2.0f, mnMaxY/2.0f, 0) - maCameraDirection)/ float(mnStepsTotal);
1105 : }
1106 :
1107 0 : void GL3DBarChart::scroll(long nDelta)
1108 : {
1109 : {
1110 0 : SharedResourceAccess aResGuard(maCond1, maCond2);
1111 0 : osl::MutexGuard aGuard(maMutex);
1112 0 : if ((maRenderEvent != EVENT_NONE) && (maRenderEvent != EVENT_SHOW_SCROLL) &&
1113 0 : (maRenderEvent != EVENT_AUTO_FLY) && (maRenderEvent != EVENT_SHOW_SELECT))
1114 0 : return;
1115 0 : glm::vec3 maDir = glm::normalize(maCameraPosition - maCameraDirection);
1116 0 : maCameraPosition -= ((float)nDelta/10) * maDir;
1117 0 : mpCamera->setPosition(maCameraPosition);
1118 0 : if(mbBenchMarkMode)
1119 : {
1120 0 : maVectorNearest.clear();
1121 0 : getNearestBars(maVectorNearest);
1122 0 : maRenderEvent = EVENT_SCROLL;
1123 0 : }
1124 : }
1125 :
1126 0 : update();
1127 : }
1128 :
1129 0 : void GL3DBarChart::contextDestroyed()
1130 : {
1131 0 : SharedResourceAccess aResGuard(maCond1, maCond2);
1132 0 : osl::MutexGuard aGuard(maMutex);
1133 0 : mbValidContext = false;
1134 0 : }
1135 :
1136 0 : float GL3DBarChart::addScreenTextShape(OUString &nStr, const glm::vec2& rLeftOrRightTop, float nTextHeight, bool bLeftTopFlag,
1137 : const glm::vec4& rColor, const glm::vec3& rPos, sal_uInt32 nEvent)
1138 : {
1139 0 : maScreenTextShapes.push_back(new opengl3D::ScreenText(mpRenderer.get(), *mpTextCache, nStr, rColor, nEvent));
1140 0 : const opengl3D::TextCacheItem& rTextCache = mpTextCache->getText(nStr);
1141 0 : float nRectWidth = (float)rTextCache.maSize.Width() / (float)rTextCache.maSize.Height() * nTextHeight / 2.0f;
1142 0 : opengl3D::ScreenText* pScreenText = static_cast<opengl3D::ScreenText*>(&maScreenTextShapes.back());
1143 0 : if (bLeftTopFlag)
1144 0 : pScreenText->setPosition(rLeftOrRightTop, glm::vec2(rLeftOrRightTop.x + nRectWidth, rLeftOrRightTop.y - nTextHeight), rPos);
1145 : else
1146 0 : pScreenText->setPosition(glm::vec2(rLeftOrRightTop.x - nRectWidth, rLeftOrRightTop.y), glm::vec2(rLeftOrRightTop.x, rLeftOrRightTop.y - nTextHeight), rPos);
1147 0 : return nRectWidth;
1148 : }
1149 :
1150 0 : void GL3DBarChart::updateRenderFPS()
1151 : {
1152 0 : int nDeltaMs = calcTimeInterval(maFPSRenderStartTime, maFPSRenderEndTime);
1153 0 : if(nDeltaMs >= FPS_TIME)
1154 : {
1155 0 : osl_getSystemTime(&maFPSRenderEndTime);
1156 0 : nDeltaMs = calcTimeInterval(maFPSRenderStartTime, maFPSRenderEndTime);
1157 0 : int iFPS = miFrameCount * 1000 / nDeltaMs;
1158 0 : maFPS = OUString::number(iFPS);
1159 0 : miFrameCount = 0;
1160 0 : osl_getSystemTime(&maFPSRenderStartTime);
1161 : }
1162 0 : osl_getSystemTime(&maFPSRenderEndTime);
1163 0 : OUString aFPS = OUString("Render FPS: ");
1164 0 : addScreenTextShape(aFPS, glm::vec2(-0.77f, 0.99f), 0.07f, false, glm::vec4(0.0f, 1.0f, 1.0f, 0.0f));
1165 : addScreenTextShape(maFPS, glm::vec2(-0.77f, 0.99f), 0.07f, true,
1166 0 : glm::vec4(1.0f, 0.0f, 0.0f, 0.0f), glm::vec3(0.0f, 0.0f, 0.0f));
1167 0 : }
1168 :
1169 0 : int GL3DBarChart::calcTimeInterval(TimeValue &startTime, TimeValue &endTime)
1170 : {
1171 : TimeValue aTime;
1172 0 : aTime.Seconds = endTime.Seconds - startTime.Seconds - 1;
1173 0 : aTime.Nanosec = 1000000000 + endTime.Nanosec - startTime.Nanosec;
1174 0 : aTime.Seconds += aTime.Nanosec / 1000000000;
1175 0 : aTime.Nanosec %= 1000000000;
1176 0 : return aTime.Seconds * 1000+aTime.Nanosec / 1000000;
1177 : }
1178 :
1179 0 : void GL3DBarChart::updateScreenText()
1180 : {
1181 0 : SharedResourceAccess aResGuard(maCond1, maCond2);
1182 0 : osl::MutexGuard aGuard(maMutex);
1183 0 : maScreenTextShapes.clear();
1184 0 : mpRenderer->ReleaseScreenTextShapes();
1185 0 : updateRenderFPS();
1186 0 : updateDataUpdateFPS();
1187 0 : updateClickEvent();
1188 0 : updateScroll();
1189 0 : mbScreenTextNewRender = true;
1190 0 : }
1191 :
1192 0 : void GL3DBarChart::updateDataUpdateFPS()
1193 : {
1194 0 : int nDeltaMs = calcTimeInterval(maDataUpdateStartTime, maDataUpdateEndTime);
1195 0 : if(nDeltaMs >= DATAUPDATE_FPS_TIME)
1196 : {
1197 0 : int iFPS = miDataUpdateCounter * 1000 / nDeltaMs;
1198 0 : if (iFPS)
1199 : {
1200 0 : maDataUpdateFPS = OUString::number(iFPS);
1201 : }
1202 : else
1203 : {
1204 0 : float fFPS = (float)miDataUpdateCounter * 1000 / (float)nDeltaMs;
1205 0 : maDataUpdateFPS = OUString::number(fFPS);
1206 : }
1207 0 : miDataUpdateCounter = 0;
1208 0 : osl_getSystemTime(&maDataUpdateStartTime);
1209 : }
1210 0 : osl_getSystemTime(&maDataUpdateEndTime);
1211 0 : OUString aDataUpdateFPS = OUString("Data Update Rate: ");
1212 0 : addScreenTextShape(aDataUpdateFPS, glm::vec2(-0.77, 0.92f), 0.07f, false, glm::vec4(0.0f, 1.0f, 1.0f, 0.0f));
1213 0 : addScreenTextShape(maDataUpdateFPS, glm::vec2(-0.77f, 0.92f), 0.07f, true, glm::vec4(1.0f, 0.0f, 0.0f, 0.0f));
1214 0 : }
1215 :
1216 0 : void GL3DBarChart::recordBarHistory(sal_uInt32 &nBarID, float &nVal)
1217 : {
1218 0 : std::list<float>& aList = maBarHistory[nBarID];
1219 0 : if(aList.size() == HISTORY_NUM)
1220 0 : aList.pop_front();
1221 0 : aList.push_back(nVal);
1222 0 : }
1223 :
1224 0 : void GL3DBarChart::getNeighborBarID(sal_uInt32 nSelectBarId, sal_uInt32 *pNeighborBarId)
1225 : {
1226 0 : sal_uInt32 nSelectRow = (nSelectBarId - SHAPE_START_ID) / ID_STEP / (mnBarsInRow + 1);
1227 0 : for (sal_Int32 i = 0; i < DISPLAY_BARS_NUM; i++)
1228 : {
1229 0 : pNeighborBarId[i] = nSelectBarId + (i - DISPLAY_BARS_NUM / 2) * ID_STEP;
1230 0 : if (pNeighborBarId[i] == nSelectBarId)
1231 0 : continue;
1232 0 : if ((pNeighborBarId[i] - SHAPE_START_ID) / ID_STEP / (mnBarsInRow + 1) != nSelectRow)
1233 0 : pNeighborBarId[i] = 0;
1234 : }
1235 0 : }
1236 :
1237 0 : void GL3DBarChart::addMovementScreenText(sal_uInt32 nBarId)
1238 : {
1239 0 : if (nBarId == 0)
1240 0 : return;
1241 0 : std::map<sal_uInt32, const BarInformation>::const_iterator itr = maBarMap.find(nBarId);
1242 0 : if (itr == maBarMap.end())
1243 0 : return;
1244 0 : const BarInformation& rBarInfo = itr->second;
1245 0 : glm::vec3 aTextPos = glm::vec3(rBarInfo.maPos.x + BAR_SIZE_X / 2.0f,
1246 0 : rBarInfo.maPos.y + BAR_SIZE_Y / 2.0f,
1247 0 : rBarInfo.maPos.z);
1248 0 : OUString aBarValue = "Value: " + OUString::number(rBarInfo.mnVal);
1249 0 : maScreenTextShapes.push_back(new opengl3D::ScreenText(mpRenderer.get(), *mpTextCache, aBarValue, glm::vec4(0.0f, 0.0f, 1.0f, 0.0f), CALC_POS_EVENT_ID, true));
1250 0 : const opengl3D::TextCacheItem& rTextCache = mpTextCache->getText(aBarValue);
1251 0 : float nRectWidth = (float)rTextCache.maSize.Width() / (float)rTextCache.maSize.Height() * 0.024;
1252 0 : opengl3D::ScreenText* pScreenText = static_cast<opengl3D::ScreenText*>(&maScreenTextShapes.back());
1253 0 : pScreenText->setPosition(glm::vec2(-nRectWidth / 2, 0.03f), glm::vec2(nRectWidth / 2, -0.03f), aTextPos);
1254 : }
1255 :
1256 0 : void GL3DBarChart::updateClickEvent()
1257 : {
1258 0 : if (maRenderEvent == EVENT_CLICK || maRenderEvent == EVENT_AUTO_FLY || maRenderEvent == EVENT_SHOW_SELECT)
1259 : {
1260 0 : std::list<float>& aList = maBarHistory[mnSelectBarId];
1261 0 : sal_uInt32 nIdex = 0;
1262 0 : sal_uInt32 nBarIdArray[DISPLAY_BARS_NUM] = {0};
1263 0 : OUString aTitle;
1264 0 : OUString aBarValue;
1265 0 : float nXCoordStart, nYCoordStart, nTextWidth, nMaxXCoord = 0.0f, nMinXCoord = 1.0f, nMaxHight = 0.0f;
1266 : //write title
1267 0 : if (aList.size() > 1)
1268 : {
1269 0 : aTitle = "Time ";
1270 0 : nTextWidth = addScreenTextShape(aTitle, glm::vec2(0.875, 0.99f), 0.07f, false, glm::vec4(0.0f, 1.0f, 1.0f, 0.5f));
1271 0 : nMinXCoord = std::min(nMinXCoord, 0.875f - nTextWidth);
1272 0 : aTitle = " Value";
1273 0 : nTextWidth = addScreenTextShape(aTitle, glm::vec2(0.875f, 0.99f), 0.07f, true, glm::vec4(0.0f, 1.0f, 1.0f, 0.5f));
1274 0 : nMaxXCoord = std::max(nMaxXCoord, 0.875f + nTextWidth);
1275 : }
1276 0 : if (aList.size() > COLUMNSIZE)
1277 : {
1278 0 : aTitle = "Time ";
1279 0 : nTextWidth = addScreenTextShape(aTitle, glm::vec2(0.55f, 0.99f), 0.07f, false, glm::vec4(0.0f, 1.0f, 1.0f, 0.5f));
1280 0 : nMinXCoord = std::min(nMinXCoord, 0.55f - nTextWidth);
1281 0 : aTitle = " Value";
1282 0 : nTextWidth = addScreenTextShape(aTitle, glm::vec2(0.55f, 0.99f), 0.07f, true, glm::vec4(0.0f, 1.0f, 1.0f, 0.5f));
1283 0 : nMaxXCoord = std::max(nMaxXCoord, 0.55f + nTextWidth);
1284 : }
1285 0 : getNeighborBarID(mnSelectBarId, nBarIdArray);
1286 0 : for (std::list<float>::iterator it = aList.begin();it != aList.end();++it)
1287 : {
1288 0 : if (nIdex + 1 < aList.size())
1289 : {
1290 0 : aTitle = "[Time:" + OUString::number((mnHistoryCounter - aList.size() + nIdex)) + "]: ";
1291 0 : if (nIdex == 0)
1292 : {
1293 0 : aTitle = "Most Recent" + aTitle;
1294 : }
1295 0 : if (aList.size() <= COLUMNSIZE)
1296 : {
1297 0 : nXCoordStart = 0.875f;
1298 0 : nYCoordStart = (nIdex + 1) * 0.07f;
1299 : }
1300 : else
1301 : {
1302 0 : nXCoordStart = nIdex < COLUMNSIZE ? 0.55f : 0.875f;
1303 0 : nYCoordStart = nIdex < COLUMNSIZE ? (nIdex + 1) * 0.07f : (nIdex - 24) * 0.07f;
1304 : }
1305 0 : nMaxHight = std::max(nMaxHight, nYCoordStart + 0.07f);
1306 0 : nTextWidth = addScreenTextShape(aTitle, glm::vec2(nXCoordStart, 0.99f - nYCoordStart), 0.07f, false, glm::vec4(0.0f, 1.0f, 1.0f, 0.5f));
1307 0 : nMinXCoord = std::min(nMinXCoord, nXCoordStart - nTextWidth);
1308 0 : aBarValue = OUString::number(*it);
1309 0 : nTextWidth = addScreenTextShape(aBarValue, glm::vec2(nXCoordStart, 0.99f - nYCoordStart), 0.07f, true, glm::vec4(0.0f, 1.0f, 1.0f, 0.5f));
1310 0 : nMaxXCoord = std::max(nMaxXCoord, nXCoordStart + nTextWidth);
1311 : }
1312 0 : nIdex++;
1313 : }
1314 0 : for (sal_uInt32 i = 0; i < DISPLAY_BARS_NUM; i++)
1315 : {
1316 0 : addMovementScreenText(nBarIdArray[i]);
1317 : }
1318 : //add translucent back ground
1319 0 : aTitle = " ";
1320 0 : maScreenTextShapes.push_back(new opengl3D::ScreenText(mpRenderer.get(), *mpTextCache, aTitle, glm::vec4(0.0f, 0.0f, 0.0f, 0.5f), 0));
1321 0 : opengl3D::ScreenText* pScreenText = static_cast<opengl3D::ScreenText*>(&maScreenTextShapes.back());
1322 0 : pScreenText->setPosition(glm::vec2(nMinXCoord, 0.99f), glm::vec2(nMaxXCoord, 0.99f - nMaxHight));
1323 : }
1324 0 : }
1325 :
1326 0 : float GL3DBarChart::calcScrollDistance(const glm::mat4& rMVP, const glm::vec3& rPos)
1327 : {
1328 0 : glm::vec4 aScreenPos = rMVP * glm::vec4(rPos, 1.0);
1329 0 : glm::vec3 aActualPos = glm::vec3(aScreenPos.x / aScreenPos.w, aScreenPos.y / aScreenPos.w, 0.0);
1330 0 : return glm::length(aActualPos);
1331 : }
1332 :
1333 0 : void GL3DBarChart::calcDistance(std::vector<sal_uInt32> & rVectorNearest)
1334 : {
1335 0 : int i =0;
1336 0 : glm::mat4 aProjection = mpRenderer->GetProjectionMatrix();
1337 0 : glm::mat4 aView = mpRenderer->GetViewMatrix();
1338 0 : glm::mat4 aScale = mpRenderer->GetGlobalScaleMatrix();
1339 0 : glm::mat4 aMVP = aProjection * aView * aScale;
1340 0 : std::map<sal_uInt32, const BarInformation>::iterator it;
1341 0 : for(it= maBarMap.begin(); it!= maBarMap.end(); ++it)
1342 : {
1343 0 : sal_uInt32 nId = it->first;
1344 0 : if(i < SHOW_VALUE_COUNT)
1345 : {
1346 0 : rVectorNearest.push_back(nId);
1347 0 : i++;
1348 : }
1349 0 : maDistanceMap[nId] = calcScrollDistance(aMVP, glm::vec3(it->second.maPos.x + BAR_SIZE_X / 2.0f,
1350 0 : it->second.maPos.y + BAR_SIZE_Y / 2.0f,
1351 0 : it->second.maPos.z));
1352 : }
1353 0 : }
1354 :
1355 0 : void GL3DBarChart::initDistanceHeap(std::vector<sal_uInt32> &rVectorNearest)
1356 : {
1357 0 : for(int i= (rVectorNearest.size()-2)/2; i>= 0; i--)
1358 : {
1359 0 : keepHeap(rVectorNearest, i);
1360 : }
1361 0 : }
1362 :
1363 0 : void GL3DBarChart::keepHeap(std::vector<sal_uInt32> &rVectorNearest, int nIndex)
1364 : {
1365 0 : size_t nParentIndex = nIndex;
1366 0 : while(nParentIndex < rVectorNearest.size())
1367 : {
1368 0 : size_t nLeftIndex = nParentIndex * 2 + 1;
1369 0 : size_t nRightIndex = nLeftIndex +1;
1370 0 : if(nLeftIndex >= rVectorNearest.size())
1371 0 : break;
1372 0 : size_t nFarthestIndex = nLeftIndex;
1373 0 : float nFarthest = maDistanceMap[rVectorNearest[nLeftIndex]];
1374 0 : if(nRightIndex < rVectorNearest.size())
1375 : {
1376 0 : float nRight = maDistanceMap[rVectorNearest[nRightIndex]];
1377 0 : if(nRight > nFarthest)
1378 : {
1379 0 : nFarthest = nRight;
1380 0 : nFarthestIndex = nRightIndex;
1381 : }
1382 : }
1383 0 : float nParent = maDistanceMap[rVectorNearest[nParentIndex]];
1384 0 : if(nParent >= nFarthest)
1385 0 : break;
1386 : else
1387 : {
1388 0 : swapVector(nParentIndex , nFarthestIndex, rVectorNearest);
1389 0 : nParentIndex = nFarthestIndex;
1390 : }
1391 : }
1392 :
1393 0 : }
1394 :
1395 0 : void GL3DBarChart::swapVector(int i, int j, std::vector<sal_uInt32> &rVectorNearest)
1396 : {
1397 0 : sal_uInt32 nTmp = rVectorNearest[i];
1398 0 : rVectorNearest[i] = rVectorNearest[j];
1399 0 : rVectorNearest[j] = nTmp;
1400 0 : }
1401 :
1402 0 : void GL3DBarChart::getNearestBars(std::vector<sal_uInt32> &rVectorNearest)
1403 : {
1404 0 : calcDistance(rVectorNearest);
1405 0 : initDistanceHeap(rVectorNearest);
1406 0 : std::map<sal_uInt32, float>::iterator it;
1407 0 : int i = 0;
1408 0 : for(it= maDistanceMap.begin(); it!= maDistanceMap.end(); ++it)
1409 : {
1410 0 : i++;
1411 0 : if(i <= SHOW_VALUE_COUNT)
1412 0 : continue;
1413 0 : float nDistance = it->second;
1414 0 : float nHeaphead = maDistanceMap[rVectorNearest[0]];
1415 0 : if(nDistance < nHeaphead)
1416 : {
1417 0 : rVectorNearest[0] = it->first;
1418 0 : keepHeap(rVectorNearest, 0);
1419 : }
1420 : }
1421 0 : }
1422 :
1423 0 : void GL3DBarChart::updateScroll()
1424 : {
1425 0 : if ((maRenderEvent == EVENT_SCROLL) || (maRenderEvent == EVENT_SHOW_SCROLL))
1426 : {
1427 0 : float fMinDistance = 0.0f;
1428 0 : std::vector<BarInformation> aBarInfoList;
1429 0 : for(size_t i= 0;i < maVectorNearest.size(); i++)
1430 : {
1431 : //get bar height position
1432 0 : std::map<sal_uInt32, const BarInformation>::const_iterator itr = maBarMap.find(maVectorNearest[i]);
1433 0 : const BarInformation& rBarInfo = itr->second;
1434 0 : aBarInfoList.push_back(rBarInfo);
1435 0 : glm::vec3 aPos = rBarInfo.maPos;
1436 0 : fMinDistance = (fMinDistance == 0.0f) ? glm::length(aPos - maCameraPosition) :
1437 0 : std::min(glm::length(aPos - maCameraPosition), fMinDistance);
1438 : }
1439 :
1440 0 : if (fMinDistance <= SHOW_SCROLL_TEXT_DISTANCE)
1441 : {
1442 : //update scroll value
1443 0 : for(size_t i = 0; i < aBarInfoList.size(); i++)
1444 : {
1445 0 : OUString aBarValue = "Value: " + OUString::number(aBarInfoList[i].mnVal);
1446 0 : maScreenTextShapes.push_back(new opengl3D::ScreenText(mpRenderer.get(), *mpTextCache, aBarValue, glm::vec4(0.0f, 0.0f, 1.0f, 0.0f), CALC_POS_EVENT_ID, true));
1447 0 : const opengl3D::TextCacheItem& rTextCache = mpTextCache->getText(aBarValue);
1448 0 : float nRectWidth = (float)rTextCache.maSize.Width() / (float)rTextCache.maSize.Height() * 0.024;
1449 0 : glm::vec3 aTextPos = glm::vec3(aBarInfoList[i].maPos.x + BAR_SIZE_X / 2.0f,
1450 0 : aBarInfoList[i].maPos.y + BAR_SIZE_Y / 2.0f,
1451 0 : aBarInfoList[i].maPos.z);
1452 0 : opengl3D::ScreenText* pScreenText = static_cast<opengl3D::ScreenText*>(&maScreenTextShapes.back());
1453 0 : pScreenText->setPosition(glm::vec2(-nRectWidth / 2, 0.03f), glm::vec2(nRectWidth / 2, -0.03f), aTextPos);
1454 0 : }
1455 0 : }
1456 : }
1457 0 : }
1458 :
1459 0 : void GL3DBarChart::processAutoFly(sal_uInt32 nId, sal_uInt32 nColor)
1460 : {
1461 : //record the color
1462 0 : sal_uInt32 nPreColor = maBarColorMap[nId];
1463 0 : maBarColorMap[nId] = nColor;
1464 : //if has manul event, just record the color and process manul event first
1465 0 : if ((maRenderEvent != EVENT_NONE))
1466 : {
1467 0 : return;
1468 : }
1469 : //calc the percentage of color change
1470 0 : int nColorRate = (nColor - nPreColor) * 100 / nPreColor;
1471 0 : nColorRate = abs(nColorRate);
1472 0 : if (nColorRate >= FLY_THRESHOLD)
1473 : {
1474 0 : maRenderEvent = EVENT_AUTO_FLY;
1475 0 : mnSelectBarId = nColorRate > mnColorRate ? nId : mnSelectBarId;
1476 0 : mnPreSelectBarId = mnSelectBarId;
1477 0 : mnColorRate = nColorRate > mnColorRate ? nColorRate : mnColorRate;
1478 : }
1479 : }
1480 :
1481 0 : IMPL_LINK_NOARG_TYPED(GL3DBarChart, UpdateTimerHdl, Idle *, void)
1482 : {
1483 0 : updateScreenText();
1484 0 : maIdle.Start();
1485 0 : }
1486 :
1487 0 : void GL3DBarChart::setOpenGLWindow(OpenGLWindow* pWindow)
1488 : {
1489 0 : if (mpWindow.get() != pWindow)
1490 : {
1491 0 : mpWindow = pWindow;
1492 0 : Size aSize = mpWindow->GetSizePixel();
1493 0 : mpRenderer->SetSize(aSize);
1494 0 : mpWindow->setRenderer(this);
1495 0 : mpWindow->getContext().makeCurrent();
1496 0 : mpRenderer->init();
1497 0 : mpWindow->getContext().resetCurrent();
1498 0 : mbValidContext = true;
1499 : }
1500 0 : }
1501 :
1502 : }
1503 :
1504 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|