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