1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.2 +++ b/os/graphics/graphicstest/uibench/s60/src/openvgengine.cpp Fri Jun 15 03:10:57 2012 +0200
1.3 @@ -0,0 +1,435 @@
1.4 + // Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
1.5 + // All rights reserved.
1.6 + // This component and the accompanying materials are made available
1.7 + // under the terms of "Eclipse Public License v1.0"
1.8 + // which accompanies this distribution, and is available
1.9 + // at the URL "http://www.eclipse.org/legal/epl-v10.html".
1.10 + //
1.11 + // Initial Contributors:
1.12 + // Nokia Corporation - initial contribution.
1.13 + //
1.14 + // Contributors:
1.15 + //
1.16 + // Description:
1.17 + //
1.18 +
1.19 +
1.20 +#include "openvgengine.h"
1.21 +#include "eglrendering.h"
1.22 +
1.23 +#include <eikenv.h>
1.24 +#include <e32math.h>
1.25 +
1.26 +
1.27 +_LIT(KCoverBitmaps, "z:\\resource\\apps\\covers.mbm");
1.28 +
1.29 +
1.30 +GLDEF_D VGUErrorCode vguComputeWarpQuadToQuadProxy(VGfloat dx0, VGfloat dy0,
1.31 + VGfloat dx1, VGfloat dy1,
1.32 + VGfloat dx2, VGfloat dy2,
1.33 + VGfloat dx3, VGfloat dy3,
1.34 + VGfloat sx0, VGfloat sy0,
1.35 + VGfloat sx1, VGfloat sy1,
1.36 + VGfloat sx2, VGfloat sy2,
1.37 + VGfloat sx3, VGfloat sy3,
1.38 + VGfloat * matrix)
1.39 + {
1.40 + vguComputeWarpQuadToQuad(
1.41 + sx0, sy0,
1.42 + sx1, sy1,
1.43 + sx2, sy2,
1.44 + sx3, sy3,
1.45 + dx0, dy0,
1.46 + dx1, dy1,
1.47 + dx2, dy2,
1.48 + dx3, dy3,
1.49 + matrix);
1.50 + return VGU_NO_ERROR;
1.51 + }
1.52 +
1.53 +COpenVGEngine* COpenVGEngine::NewL(RWindow& aWindow,EGLDisplay& aDisplay, EGLSurface& aSurface, EGLContext& aContext)
1.54 + {
1.55 + COpenVGEngine* self = new(ELeave) COpenVGEngine(aWindow, aDisplay, aSurface, aContext);
1.56 + return self;
1.57 + }
1.58 +
1.59 +COpenVGEngine::COpenVGEngine(RWindow& aWindow,EGLDisplay& aDisplay, EGLSurface& aSurface, EGLContext& aContext) :
1.60 + iWindow(aWindow), iDisplay(aDisplay), iSurface(aSurface), iContext(aContext), iWantedCover(20),
1.61 + iHasPendingDraw(EFalse), iShowCoverImage(EFalse), iSpeedOffset(0), iShowMirror(ETrue), iSpeed(0),
1.62 + iCurrentImageIndex(0)
1.63 + {
1.64 +#ifdef PORTRAIT_MODE
1.65 + iSurfaceSize.iWidth = iWindow.Size().iHeight;
1.66 + iSurfaceSize.iHeight = iWindow.Size().iWidth;
1.67 +#else
1.68 + iSurfaceSize = iWindow.Size();
1.69 +#endif
1.70 + // initiate the location of each cover & make the wanted one the cover at the opposite end
1.71 + for(TInt i = 0; i < KMaxCoversExample3; ++i)
1.72 + {
1.73 + iCoverLocation[i] = i;
1.74 + }
1.75 + }
1.76 +
1.77 +COpenVGEngine::~COpenVGEngine()
1.78 + {
1.79 + Deactivate();
1.80 + }
1.81 +
1.82 +TInt COpenVGEngine::GetSpeed()
1.83 + {
1.84 + return static_cast<TInt>(iSpeed * 100000);
1.85 + }
1.86 +
1.87 +TBool COpenVGEngine::IsPending()
1.88 + {
1.89 + return iHasPendingDraw;
1.90 + }
1.91 +
1.92 +void COpenVGEngine::ActivateL()
1.93 + {
1.94 + CEGLRendering::EGLCheckReturnError(eglMakeCurrent(iDisplay, iSurface, iSurface, iContext));
1.95 +
1.96 + // Setup initial OpenVG context state
1.97 + VGfloat clearColour[] = { 0.1f, 0.1f, 0.2f, 1.0f };
1.98 + vgSetfv(VG_CLEAR_COLOR, 4, clearColour);
1.99 + vgSeti(VG_IMAGE_QUALITY, VG_IMAGE_QUALITY_NONANTIALIASED);
1.100 + vgSeti(VG_RENDERING_QUALITY, VG_RENDERING_QUALITY_NONANTIALIASED);
1.101 + vgSeti(VG_MATRIX_MODE, VG_MATRIX_IMAGE_USER_TO_SURFACE);
1.102 +
1.103 + CFbsBitmap* bitmap = new(ELeave) CFbsBitmap();
1.104 + CleanupStack::PushL(bitmap);
1.105 + TInt idx = 0;
1.106 + while(bitmap->Load(KCoverBitmaps, idx++) == KErrNone)
1.107 + {
1.108 + VGint width = bitmap->SizeInPixels().iWidth;
1.109 + VGint height = bitmap->SizeInPixels().iHeight;
1.110 + // Crate VGImage
1.111 + VGImage image = vgCreateImage(VG_sRGB_565, width, height, VG_IMAGE_QUALITY_NONANTIALIASED);
1.112 + CEGLRendering::VGCheckError();
1.113 + //Load Symbian bitmap into VGImage
1.114 + vgImageSubData(image, bitmap->DataAddress(), bitmap->DataStride(), VG_sRGB_565, 0, 0, width, height);
1.115 + CEGLRendering::VGCheckError();
1.116 + iImages.AppendL(image);
1.117 + }
1.118 + CleanupStack::PopAndDestroy(bitmap);
1.119 + iHasPendingDraw = ETrue;
1.120 +
1.121 + //Checks if any images were loaded
1.122 + if(iImages.Count() == 0)
1.123 + {
1.124 + User::Leave(KErrNotFound);
1.125 + }
1.126 +
1.127 + iShadowPaint = vgCreatePaint();
1.128 + CEGLRendering::VGCheckError();
1.129 + if (iShadowPaint != VG_INVALID_HANDLE)
1.130 + {
1.131 + VGfloat paintColour[4] = { 0.4f, 0.4f, 0.6f, 1.0f };
1.132 + vgSetParameterfv(iShadowPaint, VG_PAINT_COLOR, 4, paintColour);
1.133 + CEGLRendering::VGCheckError();
1.134 + }
1.135 + }
1.136 +
1.137 +void COpenVGEngine::Deactivate()
1.138 + {
1.139 + CEGLRendering::EGLCheckReturnError(eglMakeCurrent(iDisplay, iSurface, iSurface, iContext));
1.140 + for (TInt i = iImages.Count() - 1; i >= 0; --i)
1.141 + {
1.142 + vgDestroyImage(iImages[i]);
1.143 + }
1.144 + vgDestroyPaint(iShadowPaint);
1.145 + eglWaitClient();
1.146 + iImages.Reset();
1.147 + iHasPendingDraw = EFalse;
1.148 + }
1.149 +
1.150 +void COpenVGEngine::Step()
1.151 + {
1.152 + CEGLRendering::EGLCheckReturnError(eglMakeCurrent(iDisplay, iSurface, iSurface, iContext));
1.153 +
1.154 +#ifdef PORTRAIT_MODE
1.155 + vgClear(0, 0, iSurfaceSize.iHeight, iSurfaceSize.iWidth);
1.156 +#else
1.157 + vgClear(0, 0, iSurfaceSize.iWidth, iSurfaceSize.iHeight);
1.158 +#endif
1.159 +
1.160 + if (Abs(iCoverLocation[iWantedCover]) < 0.03)
1.161 + {
1.162 + iSpeed = 0.0f;
1.163 + iHasPendingDraw = EFalse;
1.164 + }
1.165 + else if (Abs(iCoverLocation[iWantedCover]) < 0.5)
1.166 + {
1.167 + iSpeed *= 0.7;
1.168 + }
1.169 + else
1.170 + {
1.171 + iSpeed = 0.05 * (2 + Abs(iCoverLocation[iWantedCover]) + (Abs(iCoverLocation[iWantedCover]) + 1)
1.172 + * (Abs(iCoverLocation[iWantedCover]) + 1) / 2);
1.173 + }
1.174 + // For each Cover, update its location in the correct direction
1.175 + // Check if the wanted cover is already at the CenterStage point
1.176 +
1.177 + VGfloat moveEachCover = iSpeed;
1.178 + if (iCoverLocation[iWantedCover] > 0.0)
1.179 + {
1.180 + moveEachCover *= -1;
1.181 + }
1.182 +
1.183 + for (TInt i = 0; i < KMaxCoversExample3; ++i)
1.184 + {
1.185 + iCoverLocation[i] += moveEachCover;
1.186 + }
1.187 +
1.188 + TInt coverClippingCount = 10;
1.189 + TInt middleCoverPos = 0;
1.190 + VGfloat threshold = 0.50f;
1.191 +
1.192 + while(Abs(iCoverLocation[middleCoverPos]) > threshold)
1.193 + {
1.194 + ++middleCoverPos;
1.195 + }
1.196 +
1.197 +
1.198 + //left
1.199 + TInt cutOff = middleCoverPos - coverClippingCount;
1.200 + if (cutOff <0 )
1.201 + {
1.202 + cutOff = 0;
1.203 + }
1.204 + for (TInt i = cutOff; i < middleCoverPos; ++i)
1.205 + {
1.206 + DrawCover(i);
1.207 + }
1.208 +
1.209 + //right
1.210 + cutOff = coverClippingCount + middleCoverPos;
1.211 + if (cutOff >= KMaxCoversExample3)
1.212 + {
1.213 + cutOff = KMaxCoversExample3-1;
1.214 + }
1.215 +
1.216 + for (TInt j = cutOff; j >= middleCoverPos; --j)
1.217 + {
1.218 + DrawCover(j);
1.219 + }
1.220 +
1.221 + static TInt dir = 1;
1.222 + if (iWantedCover == (KMaxCoversExample3 - 1))
1.223 + {
1.224 + dir = -1;
1.225 + }
1.226 + else if (iWantedCover == 0)
1.227 + {
1.228 + dir = 1;
1.229 + }
1.230 +
1.231 + iWantedCover += dir;
1.232 + iHasPendingDraw = ETrue;
1.233 + }
1.234 +
1.235 +void COpenVGEngine::DrawCover(TInt coverIndex)
1.236 + {
1.237 + VGImage image = iImages[coverIndex % iImages.Count()];
1.238 + // Starting at the outside, render each visible (+/- KMaxDisplayCoversExample3/2) Cover
1.239 + // Calculate its path
1.240 + vgLoadIdentity();
1.241 +#ifdef PORTRAIT_MODE
1.242 + vgTranslate(iSurfaceSize.iHeight, 0);
1.243 + vgRotate(90);
1.244 +#endif
1.245 + VGfloat coverPosition = iCoverLocation[coverIndex];
1.246 + VGfloat tempMatrix[3][3];
1.247 +
1.248 + //flip coords
1.249 + VGfloat flipmatrix[] =
1.250 + {
1.251 + 1.0f, 0.0f, 0.0f,
1.252 + 0.0f, -1.0f, 0.0f,
1.253 + 0.0f, 0.0f, 1.0f
1.254 + };
1.255 + vgMultMatrix(flipmatrix);
1.256 + VGint imageWidth = vgGetParameteri(image, VG_IMAGE_WIDTH);
1.257 + VGint imageHeight = vgGetParameteri(image, VG_IMAGE_HEIGHT);
1.258 +
1.259 + //VGint yTrans = -200;
1.260 +
1.261 + //factors which must be multiplied with side of image which will be projected towards back
1.262 + //valid if projecting right image side to back
1.263 + //opposite is (1 - factor) for projecting left image side.
1.264 +
1.265 + VGfloat bottomProjectXFactor= (0.75f);
1.266 + VGfloat bottomProjectYFactor = (0.20f);
1.267 +
1.268 + VGfloat topProjectXFactor = (0.75f);
1.269 + VGfloat topProjectYFactor = (0.90f);
1.270 +
1.271 + VGfloat imageSpacingFactor = 0.16;
1.272 +
1.273 + VGfloat translationOffset = 0.0;
1.274 +
1.275 +
1.276 + //float yscale = 1.7;
1.277 + //float xscale = 4.4;
1.278 + //imageHeight = Min(iSurfaceSize.iWidth/xscale, iSurfaceSize.iHeight/yscale);
1.279 + //imageWidth = imageHeight;
1.280 + //TInt KImageSize = imageHeight/1.125;
1.281 + //VGint yTrans = iSurfaceSize.iHeight/-1.2;
1.282 +
1.283 + TInt KImageSize = (imageHeight * 8) / 9; //KImageSize - secondary covers should be 8/9 of the size of the middle cover
1.284 + //VGint yTrans = -200;
1.285 + VGint yTrans = - (iWindow.Size().iHeight * 5) / 6;
1.286 +
1.287 +
1.288 + VGfloat middleTranslationOffset = KImageSize / 2;
1.289 + VGfloat coverProjectionLimit = 10;
1.290 +
1.291 + if (coverPosition >= 1)
1.292 + {
1.293 + //if considering an image on the right side, this is offset from middle to place image on screen
1.294 + translationOffset = middleTranslationOffset- KImageSize/2 + KImageSize*imageSpacingFactor * (coverPosition -1);
1.295 +
1.296 + //left side of image goes back.
1.297 + vguComputeWarpQuadToQuadProxy(0.0f, 0.0f,
1.298 + imageWidth, 0.0f,
1.299 + 0.0f, imageHeight,
1.300 + imageWidth, imageHeight,
1.301 + KImageSize * (1 - bottomProjectXFactor*(1-Abs(coverPosition)/coverProjectionLimit)),KImageSize * bottomProjectYFactor,//left vertex
1.302 + KImageSize, 0.0f,
1.303 + KImageSize * (1 - topProjectXFactor*(1-Abs(coverPosition)/coverProjectionLimit)), KImageSize * topProjectYFactor,//left vertex
1.304 + KImageSize, KImageSize,
1.305 + &tempMatrix[0][0]);
1.306 + }
1.307 + else if (coverPosition < -1)
1.308 + {
1.309 + //must move an extra image width from center , as coordinates from bottom left corner of image.
1.310 + translationOffset = - (middleTranslationOffset + (KImageSize * imageSpacingFactor) * ( -coverPosition - 1) + KImageSize/2) ;
1.311 +
1.312 + vguComputeWarpQuadToQuadProxy( 0.0f, 0.0f,
1.313 + imageWidth, 0.0f,
1.314 + 0.0f, imageHeight,
1.315 + imageWidth, imageHeight,
1.316 +
1.317 + 0.0f, 0.0f,
1.318 + (bottomProjectXFactor*(1-Abs(coverPosition)/coverProjectionLimit))* KImageSize, bottomProjectYFactor * KImageSize, //Right Vertex
1.319 + 0.0f, (KImageSize),
1.320 + (topProjectXFactor*(1-Abs(coverPosition)/coverProjectionLimit)) * KImageSize, topProjectYFactor * KImageSize, //Right Vertex
1.321 +
1.322 + &tempMatrix[0][0]);
1.323 + }
1.324 + else if((coverPosition > -1) && (coverPosition <= 0))// -0.07))
1.325 + {
1.326 + translationOffset = -middleTranslationOffset * Abs(coverPosition) - KImageSize/2 ;
1.327 +
1.328 + vguComputeWarpQuadToQuadProxy( 0.0f, 0.0f,
1.329 + imageWidth, 0.0f,
1.330 + 0.0f, imageHeight,
1.331 + imageWidth, imageHeight,
1.332 + 0.0f, 0.0f,
1.333 + KImageSize * (1 - (1-bottomProjectXFactor) * Abs(coverPosition)), KImageSize * bottomProjectYFactor * Abs(coverPosition),
1.334 + 0.0f, KImageSize,
1.335 + (KImageSize * (1 - ( 1 - topProjectXFactor) * Abs(coverPosition))) , KImageSize * (1 - (1 - topProjectYFactor) * Abs(coverPosition)),
1.336 + &tempMatrix[0][0]);
1.337 + }
1.338 + else if ((coverPosition >=0) && (coverPosition <= 1))
1.339 + {
1.340 + translationOffset = middleTranslationOffset * Abs(coverPosition) - KImageSize / 2;
1.341 + vguComputeWarpQuadToQuadProxy( 0.0f, 0.0f,
1.342 + imageWidth, 0.0f,
1.343 + 0.0f, imageHeight,
1.344 + imageWidth, imageHeight,
1.345 + KImageSize * (1-bottomProjectXFactor)* (coverPosition), KImageSize * (bottomProjectYFactor) * (coverPosition),
1.346 + KImageSize, 0,
1.347 + KImageSize * ( 1 - topProjectXFactor) * (coverPosition) , KImageSize * (1 - (1 - topProjectYFactor) * Abs(coverPosition)),
1.348 + KImageSize, KImageSize,
1.349 + &tempMatrix[0][0]);
1.350 + }
1.351 + iSpeedOffset = 140*(iSpeed)*(iSpeed);
1.352 + if (iCoverLocation[iWantedCover] < 0)
1.353 + {
1.354 + iSpeedOffset *= -1;
1.355 + }
1.356 + vgTranslate(iWindow.Size().iWidth/2 + translationOffset + iSpeedOffset, yTrans);
1.357 +
1.358 + vgMultMatrix(&tempMatrix[0][0]);
1.359 + if (Abs(coverPosition) <= 1)
1.360 + {
1.361 + VGfloat scale = GetMiddleCoverScalingFactor(coverPosition);
1.362 + vgScale(scale,scale);
1.363 + vgTranslate(-(scale-1)/2 * KImageSize,-(scale-1)/2 * KImageSize);
1.364 + }
1.365 + vgDrawImage(image);
1.366 + CEGLRendering::VGCheckError();
1.367 + if (iShowMirror)
1.368 + {
1.369 + vgScale(1,-1);
1.370 + vgSeti(VG_IMAGE_MODE, VG_DRAW_IMAGE_MULTIPLY);
1.371 + vgTranslate(0,-4*KImageSize+226);
1.372 + //vgTranslate(0,iSurfaceSize.iHeight/-.839);
1.373 +
1.374 + vgSetPaint(iShadowPaint, VG_FILL_PATH);
1.375 + vgDrawImage(image);
1.376 + CEGLRendering::VGCheckError();
1.377 +
1.378 + vgSeti(VG_IMAGE_MODE,VG_DRAW_IMAGE_NORMAL);
1.379 + }
1.380 + }
1.381 +
1.382 +TKeyResponse COpenVGEngine::HandleKeyEventL(const TKeyEvent& aKeyEvent)
1.383 + {
1.384 + TKeyResponse response = EKeyWasConsumed;
1.385 + switch (aKeyEvent.iCode)
1.386 + {
1.387 + case EKeyRightArrow:
1.388 + NextCover();
1.389 + break;
1.390 + case EKeyLeftArrow:
1.391 + PreviousCover();
1.392 + break;
1.393 + case EKeyBackspace:
1.394 + ToggleCoverReflection();
1.395 + break;
1.396 + default:
1.397 + response = EKeyWasNotConsumed;
1.398 + break;
1.399 + };
1.400 + return response;
1.401 + }
1.402 +
1.403 +void COpenVGEngine::NextCover()
1.404 + {
1.405 + if (iWantedCover < (KMaxCoversExample3 - 1))
1.406 + {
1.407 + ++iWantedCover;
1.408 + iHasPendingDraw = ETrue;
1.409 + }
1.410 + }
1.411 +
1.412 +void COpenVGEngine::PreviousCover()
1.413 + {
1.414 + if (iWantedCover > 0)
1.415 + {
1.416 + --iWantedCover;
1.417 + iHasPendingDraw = ETrue;
1.418 + }
1.419 + }
1.420 +
1.421 +void COpenVGEngine::ToggleCoverReflection()
1.422 + {
1.423 + iShowMirror = !iShowMirror;
1.424 + }
1.425 +
1.426 +VGfloat COpenVGEngine::GetMiddleCoverScalingFactor(VGfloat aCoverPosition)
1.427 + {
1.428 + if(Abs(aCoverPosition) > 1)
1.429 + {
1.430 + return 0.0f;
1.431 + }
1.432 + return (-0.125 * Abs(aCoverPosition) + 1.125);
1.433 + }
1.434 +
1.435 +void COpenVGEngine::Refresh()
1.436 + {
1.437 + iHasPendingDraw = ETrue;
1.438 + }