First public contribution.
1 // Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
2 // All rights reserved.
3 // This component and the accompanying materials are made available
4 // under the terms of "Eclipse Public License v1.0"
5 // which accompanies this distribution, and is available
6 // at the URL "http://www.eclipse.org/legal/epl-v10.html".
8 // Initial Contributors:
9 // Nokia Corporation - initial contribution.
17 #include "openvgengine.h"
18 #include "eglrendering.h"
24 _LIT(KCoverBitmaps, "z:\\resource\\apps\\covers.mbm");
27 GLDEF_D VGUErrorCode vguComputeWarpQuadToQuadProxy(VGfloat dx0, VGfloat dy0,
28 VGfloat dx1, VGfloat dy1,
29 VGfloat dx2, VGfloat dy2,
30 VGfloat dx3, VGfloat dy3,
31 VGfloat sx0, VGfloat sy0,
32 VGfloat sx1, VGfloat sy1,
33 VGfloat sx2, VGfloat sy2,
34 VGfloat sx3, VGfloat sy3,
37 vguComputeWarpQuadToQuad(
50 COpenVGEngine* COpenVGEngine::NewL(RWindow& aWindow,EGLDisplay& aDisplay, EGLSurface& aSurface, EGLContext& aContext)
52 COpenVGEngine* self = new(ELeave) COpenVGEngine(aWindow, aDisplay, aSurface, aContext);
56 COpenVGEngine::COpenVGEngine(RWindow& aWindow,EGLDisplay& aDisplay, EGLSurface& aSurface, EGLContext& aContext) :
57 iWindow(aWindow), iDisplay(aDisplay), iSurface(aSurface), iContext(aContext), iWantedCover(20),
58 iHasPendingDraw(EFalse), iShowCoverImage(EFalse), iSpeedOffset(0), iShowMirror(ETrue), iSpeed(0),
62 iSurfaceSize.iWidth = iWindow.Size().iHeight;
63 iSurfaceSize.iHeight = iWindow.Size().iWidth;
65 iSurfaceSize = iWindow.Size();
67 // initiate the location of each cover & make the wanted one the cover at the opposite end
68 for(TInt i = 0; i < KMaxCoversExample3; ++i)
70 iCoverLocation[i] = i;
74 COpenVGEngine::~COpenVGEngine()
79 TInt COpenVGEngine::GetSpeed()
81 return static_cast<TInt>(iSpeed * 100000);
84 TBool COpenVGEngine::IsPending()
86 return iHasPendingDraw;
89 void COpenVGEngine::ActivateL()
91 CEGLRendering::EGLCheckReturnError(eglMakeCurrent(iDisplay, iSurface, iSurface, iContext));
93 // Setup initial OpenVG context state
94 VGfloat clearColour[] = { 0.1f, 0.1f, 0.2f, 1.0f };
95 vgSetfv(VG_CLEAR_COLOR, 4, clearColour);
96 vgSeti(VG_IMAGE_QUALITY, VG_IMAGE_QUALITY_NONANTIALIASED);
97 vgSeti(VG_RENDERING_QUALITY, VG_RENDERING_QUALITY_NONANTIALIASED);
98 vgSeti(VG_MATRIX_MODE, VG_MATRIX_IMAGE_USER_TO_SURFACE);
100 CFbsBitmap* bitmap = new(ELeave) CFbsBitmap();
101 CleanupStack::PushL(bitmap);
103 while(bitmap->Load(KCoverBitmaps, idx++) == KErrNone)
105 VGint width = bitmap->SizeInPixels().iWidth;
106 VGint height = bitmap->SizeInPixels().iHeight;
108 VGImage image = vgCreateImage(VG_sRGB_565, width, height, VG_IMAGE_QUALITY_NONANTIALIASED);
109 CEGLRendering::VGCheckError();
110 //Load Symbian bitmap into VGImage
111 vgImageSubData(image, bitmap->DataAddress(), bitmap->DataStride(), VG_sRGB_565, 0, 0, width, height);
112 CEGLRendering::VGCheckError();
113 iImages.AppendL(image);
115 CleanupStack::PopAndDestroy(bitmap);
116 iHasPendingDraw = ETrue;
118 //Checks if any images were loaded
119 if(iImages.Count() == 0)
121 User::Leave(KErrNotFound);
124 iShadowPaint = vgCreatePaint();
125 CEGLRendering::VGCheckError();
126 if (iShadowPaint != VG_INVALID_HANDLE)
128 VGfloat paintColour[4] = { 0.4f, 0.4f, 0.6f, 1.0f };
129 vgSetParameterfv(iShadowPaint, VG_PAINT_COLOR, 4, paintColour);
130 CEGLRendering::VGCheckError();
134 void COpenVGEngine::Deactivate()
136 CEGLRendering::EGLCheckReturnError(eglMakeCurrent(iDisplay, iSurface, iSurface, iContext));
137 for (TInt i = iImages.Count() - 1; i >= 0; --i)
139 vgDestroyImage(iImages[i]);
141 vgDestroyPaint(iShadowPaint);
144 iHasPendingDraw = EFalse;
147 void COpenVGEngine::Step()
149 CEGLRendering::EGLCheckReturnError(eglMakeCurrent(iDisplay, iSurface, iSurface, iContext));
152 vgClear(0, 0, iSurfaceSize.iHeight, iSurfaceSize.iWidth);
154 vgClear(0, 0, iSurfaceSize.iWidth, iSurfaceSize.iHeight);
157 if (Abs(iCoverLocation[iWantedCover]) < 0.03)
160 iHasPendingDraw = EFalse;
162 else if (Abs(iCoverLocation[iWantedCover]) < 0.5)
168 iSpeed = 0.05 * (2 + Abs(iCoverLocation[iWantedCover]) + (Abs(iCoverLocation[iWantedCover]) + 1)
169 * (Abs(iCoverLocation[iWantedCover]) + 1) / 2);
171 // For each Cover, update its location in the correct direction
172 // Check if the wanted cover is already at the CenterStage point
174 VGfloat moveEachCover = iSpeed;
175 if (iCoverLocation[iWantedCover] > 0.0)
180 for (TInt i = 0; i < KMaxCoversExample3; ++i)
182 iCoverLocation[i] += moveEachCover;
185 TInt coverClippingCount = 10;
186 TInt middleCoverPos = 0;
187 VGfloat threshold = 0.50f;
189 while(Abs(iCoverLocation[middleCoverPos]) > threshold)
196 TInt cutOff = middleCoverPos - coverClippingCount;
201 for (TInt i = cutOff; i < middleCoverPos; ++i)
207 cutOff = coverClippingCount + middleCoverPos;
208 if (cutOff >= KMaxCoversExample3)
210 cutOff = KMaxCoversExample3-1;
213 for (TInt j = cutOff; j >= middleCoverPos; --j)
219 if (iWantedCover == (KMaxCoversExample3 - 1))
223 else if (iWantedCover == 0)
229 iHasPendingDraw = ETrue;
232 void COpenVGEngine::DrawCover(TInt coverIndex)
234 VGImage image = iImages[coverIndex % iImages.Count()];
235 // Starting at the outside, render each visible (+/- KMaxDisplayCoversExample3/2) Cover
236 // Calculate its path
239 vgTranslate(iSurfaceSize.iHeight, 0);
242 VGfloat coverPosition = iCoverLocation[coverIndex];
243 VGfloat tempMatrix[3][3];
246 VGfloat flipmatrix[] =
252 vgMultMatrix(flipmatrix);
253 VGint imageWidth = vgGetParameteri(image, VG_IMAGE_WIDTH);
254 VGint imageHeight = vgGetParameteri(image, VG_IMAGE_HEIGHT);
256 //VGint yTrans = -200;
258 //factors which must be multiplied with side of image which will be projected towards back
259 //valid if projecting right image side to back
260 //opposite is (1 - factor) for projecting left image side.
262 VGfloat bottomProjectXFactor= (0.75f);
263 VGfloat bottomProjectYFactor = (0.20f);
265 VGfloat topProjectXFactor = (0.75f);
266 VGfloat topProjectYFactor = (0.90f);
268 VGfloat imageSpacingFactor = 0.16;
270 VGfloat translationOffset = 0.0;
273 //float yscale = 1.7;
274 //float xscale = 4.4;
275 //imageHeight = Min(iSurfaceSize.iWidth/xscale, iSurfaceSize.iHeight/yscale);
276 //imageWidth = imageHeight;
277 //TInt KImageSize = imageHeight/1.125;
278 //VGint yTrans = iSurfaceSize.iHeight/-1.2;
280 TInt KImageSize = (imageHeight * 8) / 9; //KImageSize - secondary covers should be 8/9 of the size of the middle cover
281 //VGint yTrans = -200;
282 VGint yTrans = - (iWindow.Size().iHeight * 5) / 6;
285 VGfloat middleTranslationOffset = KImageSize / 2;
286 VGfloat coverProjectionLimit = 10;
288 if (coverPosition >= 1)
290 //if considering an image on the right side, this is offset from middle to place image on screen
291 translationOffset = middleTranslationOffset- KImageSize/2 + KImageSize*imageSpacingFactor * (coverPosition -1);
293 //left side of image goes back.
294 vguComputeWarpQuadToQuadProxy(0.0f, 0.0f,
297 imageWidth, imageHeight,
298 KImageSize * (1 - bottomProjectXFactor*(1-Abs(coverPosition)/coverProjectionLimit)),KImageSize * bottomProjectYFactor,//left vertex
300 KImageSize * (1 - topProjectXFactor*(1-Abs(coverPosition)/coverProjectionLimit)), KImageSize * topProjectYFactor,//left vertex
301 KImageSize, KImageSize,
304 else if (coverPosition < -1)
306 //must move an extra image width from center , as coordinates from bottom left corner of image.
307 translationOffset = - (middleTranslationOffset + (KImageSize * imageSpacingFactor) * ( -coverPosition - 1) + KImageSize/2) ;
309 vguComputeWarpQuadToQuadProxy( 0.0f, 0.0f,
312 imageWidth, imageHeight,
315 (bottomProjectXFactor*(1-Abs(coverPosition)/coverProjectionLimit))* KImageSize, bottomProjectYFactor * KImageSize, //Right Vertex
317 (topProjectXFactor*(1-Abs(coverPosition)/coverProjectionLimit)) * KImageSize, topProjectYFactor * KImageSize, //Right Vertex
321 else if((coverPosition > -1) && (coverPosition <= 0))// -0.07))
323 translationOffset = -middleTranslationOffset * Abs(coverPosition) - KImageSize/2 ;
325 vguComputeWarpQuadToQuadProxy( 0.0f, 0.0f,
328 imageWidth, imageHeight,
330 KImageSize * (1 - (1-bottomProjectXFactor) * Abs(coverPosition)), KImageSize * bottomProjectYFactor * Abs(coverPosition),
332 (KImageSize * (1 - ( 1 - topProjectXFactor) * Abs(coverPosition))) , KImageSize * (1 - (1 - topProjectYFactor) * Abs(coverPosition)),
335 else if ((coverPosition >=0) && (coverPosition <= 1))
337 translationOffset = middleTranslationOffset * Abs(coverPosition) - KImageSize / 2;
338 vguComputeWarpQuadToQuadProxy( 0.0f, 0.0f,
341 imageWidth, imageHeight,
342 KImageSize * (1-bottomProjectXFactor)* (coverPosition), KImageSize * (bottomProjectYFactor) * (coverPosition),
344 KImageSize * ( 1 - topProjectXFactor) * (coverPosition) , KImageSize * (1 - (1 - topProjectYFactor) * Abs(coverPosition)),
345 KImageSize, KImageSize,
348 iSpeedOffset = 140*(iSpeed)*(iSpeed);
349 if (iCoverLocation[iWantedCover] < 0)
353 vgTranslate(iWindow.Size().iWidth/2 + translationOffset + iSpeedOffset, yTrans);
355 vgMultMatrix(&tempMatrix[0][0]);
356 if (Abs(coverPosition) <= 1)
358 VGfloat scale = GetMiddleCoverScalingFactor(coverPosition);
359 vgScale(scale,scale);
360 vgTranslate(-(scale-1)/2 * KImageSize,-(scale-1)/2 * KImageSize);
363 CEGLRendering::VGCheckError();
367 vgSeti(VG_IMAGE_MODE, VG_DRAW_IMAGE_MULTIPLY);
368 vgTranslate(0,-4*KImageSize+226);
369 //vgTranslate(0,iSurfaceSize.iHeight/-.839);
371 vgSetPaint(iShadowPaint, VG_FILL_PATH);
373 CEGLRendering::VGCheckError();
375 vgSeti(VG_IMAGE_MODE,VG_DRAW_IMAGE_NORMAL);
379 TKeyResponse COpenVGEngine::HandleKeyEventL(const TKeyEvent& aKeyEvent)
381 TKeyResponse response = EKeyWasConsumed;
382 switch (aKeyEvent.iCode)
391 ToggleCoverReflection();
394 response = EKeyWasNotConsumed;
400 void COpenVGEngine::NextCover()
402 if (iWantedCover < (KMaxCoversExample3 - 1))
405 iHasPendingDraw = ETrue;
409 void COpenVGEngine::PreviousCover()
411 if (iWantedCover > 0)
414 iHasPendingDraw = ETrue;
418 void COpenVGEngine::ToggleCoverReflection()
420 iShowMirror = !iShowMirror;
423 VGfloat COpenVGEngine::GetMiddleCoverScalingFactor(VGfloat aCoverPosition)
425 if(Abs(aCoverPosition) > 1)
429 return (-0.125 * Abs(aCoverPosition) + 1.125);
432 void COpenVGEngine::Refresh()
434 iHasPendingDraw = ETrue;