plugin/poi/landmarks/object/src/Object.cpp
changeset 0 c316ab048e9d
equal deleted inserted replaced
-1:000000000000 0:c316ab048e9d
       
     1 /*
       
     2  * Name        : Object.cpp
       
     3  * Description : 
       
     4  * Project     : This file is part of OpenMAR, an Open Mobile Augmented Reality browser
       
     5  * Website     : http://OpenMAR.org
       
     6  *
       
     7  * Copyright (c) 2010 David Caabeiro
       
     8  *
       
     9  * All rights reserved. This program and the accompanying materials are made available 
       
    10  * under the terms of the Eclipse Public License v1.0 which accompanies this 
       
    11  * distribution, and is available at http://www.eclipse.org/legal/epl-v10.html
       
    12  *
       
    13  */
       
    14 
       
    15 #include "Object.h"
       
    16 
       
    17 #include "IconLoader.h"
       
    18 #include "Vector3d.h"
       
    19 
       
    20 #include <bitdev.h>
       
    21 #include <bitstd.h>
       
    22 #include <fbs.h>
       
    23 #include <GulIcon.h>
       
    24 #include <GLES/egl.h>
       
    25 
       
    26 #include <Landmarks_0x2002E1AF.mbg>
       
    27 
       
    28 #include "Logger.h"
       
    29 
       
    30 CLMXObject* CLMXObject::NewL(OpenMAR::CPOIProvider* aProvider)
       
    31 {
       
    32     CLMXObject* self = new(ELeave) CLMXObject(aProvider);
       
    33     CleanupStack::PushL(self);
       
    34     self->ConstructL();
       
    35     CleanupStack::Pop(self);
       
    36 
       
    37     return self;
       
    38 }
       
    39 
       
    40 CLMXObject::~CLMXObject()
       
    41 {
       
    42     ::glDeleteTextures(1, &iTextureId);
       
    43 }
       
    44 
       
    45 CLMXObject::CLMXObject(OpenMAR::CPOIProvider* aProvider)
       
    46     : OpenMAR::CPOIObject(*aProvider)
       
    47 {}
       
    48 
       
    49 /*
       
    50  * Landmark objects will make use of an SVG file for rendering (demo purposes)
       
    51  */
       
    52 void CLMXObject::ConstructL()
       
    53 {
       
    54     _LIT(KIconFile, "\\resource\\apps\\Landmarks_0x2002E1AF.mif");
       
    55 
       
    56     CGulIcon* icon = CreateIconL(KIconFile, EMbmLandmarks_0x2002e1afIcon, EMbmLandmarks_0x2002e1afIcon_mask);
       
    57     CleanupStack::PushL(icon);
       
    58 
       
    59     CFbsBitmap* bitmap = icon->Bitmap();    // Ownership NOT transferred
       
    60     CFbsBitmap* mask   = icon->Mask();      // Ownership NOT transferred
       
    61 
       
    62     // Always expect 16M bitmap to make conversion to GL_RGBA easier 
       
    63     if (bitmap->DisplayMode() != EColor16M)
       
    64     {
       
    65         bitmap = new(ELeave) CFbsBitmap;
       
    66         CleanupStack::PushL(bitmap);
       
    67 
       
    68         User::LeaveIfError(bitmap->Create(icon->Bitmap()->SizeInPixels(), EColor16M));
       
    69 
       
    70         CFbsBitmapDevice* bitmapDevice = CFbsBitmapDevice::NewL(bitmap);
       
    71         CleanupStack::PushL(bitmapDevice);
       
    72 
       
    73         CFbsBitGc* bitmapContext = 0;
       
    74         User::LeaveIfError(bitmapDevice->CreateContext(bitmapContext));
       
    75         CleanupStack::PushL(bitmapContext);
       
    76 
       
    77         bitmapContext->BitBlt(TPoint(0, 0), icon->Bitmap());
       
    78 
       
    79         CleanupStack::PopAndDestroy(2, bitmapDevice);
       
    80 
       
    81         icon->SetBitmap(bitmap);    // Ownership transferred
       
    82 
       
    83         CleanupStack::Pop(bitmap);
       
    84     }
       
    85 
       
    86     // Always expect 256 mask to make conversion to GL_RGBA easier 
       
    87     if (mask->DisplayMode() != EGray256)
       
    88     {
       
    89         mask = new(ELeave) CFbsBitmap;
       
    90         CleanupStack::PushL(mask);
       
    91 
       
    92         User::LeaveIfError(mask->Create(icon->Mask()->SizeInPixels(), EGray256));
       
    93 
       
    94         CFbsBitmapDevice* bitmapDevice = CFbsBitmapDevice::NewL(mask);
       
    95         CleanupStack::PushL(bitmapDevice);
       
    96 
       
    97         CFbsBitGc* bitmapContext = 0;
       
    98         User::LeaveIfError(bitmapDevice->CreateContext(bitmapContext));
       
    99         CleanupStack::PushL(bitmapContext);
       
   100 
       
   101         bitmapContext->BitBlt(TPoint(0, 0), icon->Mask());
       
   102 
       
   103         CleanupStack::PopAndDestroy(2, bitmapDevice);
       
   104 
       
   105         icon->SetMask(mask);    // Ownership transferred
       
   106 
       
   107         CleanupStack::Pop(mask);
       
   108     }
       
   109 
       
   110     // Now bitmap and mask point to either original or converted bitmaps, 
       
   111     // and ownership belongs to icon
       
   112 
       
   113     const TSize bitmapSize = bitmap->SizeInPixels();
       
   114 
       
   115     // sizeof(TUint32) == sizeof(RGBA)
       
   116     const TInt dataSize = bitmapSize.iWidth * bitmapSize.iHeight * sizeof(TUint32);
       
   117     TUint8* data = new(ELeave) TUint8[dataSize];
       
   118 
       
   119     // Perform copy and conversion from BGR(A) to RGB(A)
       
   120     bitmap->LockHeap();
       
   121     mask->LockHeap();
       
   122 
       
   123     // TODO: Alpha component removed, as it seems to be corrupted from
       
   124     // subsequent reads from SVG file
       
   125 
       
   126     TUint8* rgb = reinterpret_cast<TUint8*>(bitmap->DataAddress());
       
   127 //    TUint8* alpha = reinterpret_cast<TUint8*>(mask->DataAddress());
       
   128 
       
   129     for(TInt i = 0, j = 0; i < dataSize; i += 4, j += 3)
       
   130     {
       
   131         data[i + 0] = rgb[j + 2];
       
   132         data[i + 1] = rgb[j + 1];
       
   133         data[i + 2] = rgb[j + 0];
       
   134         data[i + 3] = 0xc0; //alpha[i / 4];
       
   135     }
       
   136 
       
   137     // Generate OpenGL texture
       
   138     ::glGenTextures(1, &iTextureId); 
       
   139     ::glBindTexture(GL_TEXTURE_2D, iTextureId);
       
   140 
       
   141     ::glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
       
   142     ::glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
       
   143     ::glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
       
   144     ::glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
       
   145 
       
   146     ::glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, bitmapSize.iWidth, bitmapSize.iHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE, data);
       
   147 
       
   148     mask->UnlockHeap();
       
   149     bitmap->UnlockHeap();
       
   150 
       
   151     delete data;
       
   152 
       
   153     CleanupStack::PopAndDestroy(icon);
       
   154 }
       
   155 
       
   156 void CLMXObject::Render() const
       
   157 {
       
   158     /*
       
   159      * This is a special case for points or planes in space. Given that a usual POI
       
   160      * does not provide of any transformation to be applied on it, we determine the
       
   161      * angle in the XY plane with respect to the observer and apply that rotation to 
       
   162      * the object.
       
   163      *
       
   164      * This way, all POIs will face the observer regardless their position. Other
       
   165      * objects (3D Landmarks, etc) should provide their own transformations in some
       
   166      * proper way.   
       
   167      */
       
   168 
       
   169     TReal angle = 0;
       
   170     Math::ATan(angle, iPosition.mX, iPosition.mY);
       
   171     angle *= -KRadToDeg;
       
   172 
       
   173     /*
       
   174      * We could also apply some scaling calculation to compensate the size of
       
   175      * objects projected at a long distance from the camera.
       
   176      * For now we just use a constant value
       
   177      */
       
   178 
       
   179     TReal scale = 64.0f;
       
   180 
       
   181     // Apply transformations to the object and render it
       
   182 
       
   183     const TInt unity = 1 << 16;
       
   184 
       
   185     GLfixed vertices[] = {
       
   186         -unity / 2, 0, 0,
       
   187          unity / 2, 0, 0,
       
   188         -unity / 2, 0, unity,
       
   189          unity / 2, 0, unity,
       
   190     };
       
   191 
       
   192     GLfixed texCoords[] = {
       
   193         0,      unity,
       
   194         unity,  unity,
       
   195         0,      0,
       
   196         unity,  0
       
   197     };
       
   198 
       
   199     ::glPushMatrix();
       
   200 
       
   201     ::glTranslatef(iPosition.mX, iPosition.mY, iPosition.mZ);
       
   202     ::glRotatef(angle, 0, 0, 1);
       
   203     ::glScalef(scale, 1.0f, scale);
       
   204 
       
   205     ::glEnable(GL_TEXTURE_2D);
       
   206     ::glBindTexture(GL_TEXTURE_2D, iTextureId);
       
   207     ::glVertexPointer(3, GL_FIXED, 0, vertices);
       
   208     ::glTexCoordPointer(2, GL_FIXED, 0, texCoords);
       
   209     ::glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
       
   210     ::glDisable(GL_TEXTURE_2D);
       
   211 
       
   212     ::glPopMatrix();
       
   213 }