FAQ

  1. General
  2. All Platforms
  3. iOS
  4. Android

General

Where can I find further information on the sample data?

For further information on the sample data provided with the VisioDevKit sample, please write to contact@visioglobe.com

Who can I contact if I need help?

Please send your questions and/or feedback to support@visioglobe.com

All Platforms

When I try to run an example I get the following pop up alert error:
 Invalid license

Below is a trouble shooting guide to help identify the problem.

  • Verify the secret code used when loading configuration (VgEngine::VgIDatabase::loadConfiguration) is correct.
  • Verify the license id used when loading configuration (VgEngine::VgIDatabase::loadConfiguration) is correct.
  • Verify your device (or simulator) can access the Internet and the url. An Internet connection is required to get the license.
When I load a texture and add it to the scene (using a VgPoint for example), the image appears as a white square.

This implies that the image texture hasn't been loaded correctly. A possible reason why is because it wasn't loaded from within the same thread as the Open GL surface.

iOS

I compile VisioSample for the device and I get the following error:
 Code Sign error: a valid provisioning profile matching the application identifier "com.yourcompany.VisioSample" could not be found

When you compile for the device, you need to be registered in the iOS Developer Program and have your Xcode certificates and provisioning profiles set up.

If that's the case then don't forget to update the application's Bundle Identifier (inside *.plist file) with your company’s name (or a name matching your Provisioning profile) and verify your Code Signing Identity in your project settings.

How do I create an AdHoc version?

Projects are setup for developer signing. To create AdHoc versions, you need to add Entitlements.plist to Code Signing Entitlements and change the Code Signing Identity to iOS Distribution.

When I try to run the VisioSample example I get the following pop up alert error:
 viewDidLoad: loadConfiguration failed Configuration file missing

Verify that the Data directory is correctly added to the VisioSample project. If it's not then add it as a folder (and not a group) from ../../Data (relative to project). If it is correctly added to the VisioSample project, then verify that the following file Data/PVRTC/vg_config.xml exists and is valid.

When I run the example, the console displays the following message and receives a SIGABRT or a EXC_BAD_ACCESS message :
 Unknown class VgEAGLView in Interface Builder

In the project/target settings, disable the dead code stripping option.

When I run the example, I receive a EXC_BAD_ACCESS on the following instruction :
  [[VgEAGLView alloc] initWithFrame :rect] 

In the project/target settings, disable the Compress PNG option.

My application contains PNG files, so I want to let the Compress PNG option enabled, but I still want to use images as texture for POIs

You have three solutions:

  • Use JPG file for POIs
  • Change the file type of the PNGs you want to use as texture (with the File Inspector in XCode4).
  • Change your file extension to avoid XCode processing them (example : "png_")
After performing a four finger swipe gesture, the camera manipulator is left in a blocked state

Resetting the state of the current camera manipulator can be achieved with the below method:

    [myVgEAGLViewInstance setRenderSuspended : NO];
When I run my application containing a VgEAGLView in the background, the application crashes

iOS doesn't support the rendering of EAGLView's while they are in a background task (gpu access not permitted). The solution is to stop rendering the VgEAGLView when the application passes into the background. This can be achieved using the following code.

// constructor
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(handleDidBecomeActive:) name:UIApplicationDidBecomeActiveNotification object:nil];
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(handleWillResign:) name:UIApplicationWillResignActiveNotification object:nil];


// Start rendering when application is active
-(void) handleDidBecomeActive:(id)pSender
{
    [myVgEAGLViewInstance setRenderSuspended : NO];
}

// Stop rendering when application has resigned.
-(void) handleWillResign:(id)pSender
{
    [myVgEAGLViewInstance setRenderSuspended : YES];
}

// dealloc
    [[NSNotificationCenter defaultCenter] removeObserver:self];
POIs with my custom images do not appear on some devices

Some GPU do not support images whose sizes are not power of two, or not square. Search in all your images for those which do not match these requirements. There are two solutions. Choose the one that best fit your needs and your workflow.

  • Resize manually the invalid images.
  • Add the following code snippet to automatically resize images. So instead of calling VgEngine::VgIResourceManager::readFromFileOrURL, use imageToBuffer(...) which is defined below.
 static unsigned int roundUpToNextPowerOfTwo (unsigned int x)
 {
 x--;
 x |= x >> 1;      // handle  2 bit numbers
 x |= x >> 2;      // handle  4 bit numbers
 x |= x >> 4;      // handle  8 bit numbers
 x |= x >> 8;      // handle 16 bit numbers
 x |= x >> 16;     // handle 32 bit numbers
 x++;
 return x;
 }
 
VgEngine::VgBinaryBuffer* imageToBuffer (const std::string& pImageName)
{
    NSString* lImageName = [NSString stringWithUTF8String:pImageName.c_str()];
    
    UIImage* lIcon = [UIImage imageWithContentsOfFile:lImageName];
    if ( lIcon == nil || lIcon.CGImage == NULL )
    {
        return NULL;
    }
    
    CGImage* lIconImage = lIcon.CGImage;
    int lWidth = CGImageGetWidth(lIconImage);
    int lHeight = CGImageGetHeight(lIconImage);
    lWidth = roundUpToNextPowerOfTwo(lWidth);
    lHeight = roundUpToNextPowerOfTwo(lHeight);
    
    // lIconData will be allocated and freed by VgBuffer.
    Byte* lIconData = NULL;
    
    // lIconData will be updated after this call, so we know where to put the incoming image.
    VgEngine::VgBinaryBuffer* lBuffer = VgEngine::VgImage::prepareTextureBuffer(lWidth, lHeight, VgEngine::VgImage::eRGBA, lIconData);
    if ( lBuffer->getLength() == 0 )
    {
        return NULL;
    }
    
    // Create a Bitmap Context with the buffer.
    CGColorSpaceRef lColorSpace = CGColorSpaceCreateDeviceRGB();
    CGContextRef lCgContext = CGBitmapContextCreate(lIconData, lWidth, lHeight, 8, lWidth * 4, lColorSpace, kCGImageAlphaPremultipliedLast);
    if ( lCgContext != NULL )
    {
        // Set the blend mode to copy. We don't care about the previous contents.
        CGContextSetBlendMode(lCgContext, kCGBlendModeCopy);
        // Render the UIImage in the context, thus in the buffer.
        CGContextDrawImage(lCgContext, CGRectMake(0.0f, 0.0f, lWidth, lHeight), lIconImage);
        CGContextRelease(lCgContext);
    }
    CGColorSpaceRelease(lColorSpace);
    
    bool lFlipImage = true;
    if ( lFlipImage )
    {
        // Flip Image
        // gl renders "upside down" so swap top to bottom into new array.
        // there's gotta be a better way, but this works.
        //GLubyte *buffer2 = (GLubyte *) malloc(myDataLength);
        unsigned char* buffer = lIconData;
        // if lWidth not multiple of 4, use characters in your loop.
        if ((lWidth % 4) != 0 )
        {
            for ( int y = 0; y < lHeight / 2; y++ )
            {
                for ( int x = 0; x < lWidth * 4; x++ )
                {
                    unsigned char t = buffer[(lHeight - 1 - y) * lWidth * 4 + x];
                    buffer[(lHeight - 1 - y) * lWidth * 4 + x] = buffer[y * 4 * lWidth + x];
                    buffer[y * 4 * lWidth + x] = t;
                }
            }
        }
        else
        {
            unsigned int* pBuffer = (unsigned int*)buffer;
            unsigned int lFromIndex = (lHeight - 1) * lWidth;
            unsigned int lToIndex = 0;
            for ( int y = 0; y < lHeight / 2; y++ )
            {
                for ( int x = 0; x < lWidth; x++ )
                {
                    unsigned int tmp = pBuffer[lFromIndex + x];
                    pBuffer[lFromIndex + x] = pBuffer[lToIndex + x];
                    pBuffer[lToIndex + x] = tmp;
                }
                lFromIndex -= lWidth;
                lToIndex += lWidth;
            }
        }
    }
    return lBuffer;
}
When I compile my project with the VisioDevKit library, I get the following error:
        (null): Illegal text-relocoation (direct reference) to (global,weak) ...

Version VisioDevKit-2.0.7445.7445-20120917 and earlier of VisioDevKit had the Generate Position-Dependent compiler option set to "YES". This started to become a problem in Xcode 4.5 and caused the above linking error in applications using the VisioDevKit library. If you're using a previous version of VisioDevKit and you're getting a linking error similar to above, then you can solve the problem by setting you project's Generate Position-Dependent compiler flag to "NO". Note: For later versions of VisioDevKit the compiler option Generate Position-Dependent is set to "NO". This means the project that includes the VisioDevKit library may use the Generate Position-Dependent compiler setting as they see fit without getting the above linking error.

How can I change the background image?

This is configurable within the data bundle's vg_config.xml file. Currently, PNG images are supported. Restraints include: the image must have dimensions which are a power of two; the image should be stored in the data bundle's "images" directory.

// <!-- vg_config.xml -->    
<resources>
...
    <textures>
        <texture id="background_id" resource="my_background_file_name.png"/>
...
<datasets>
    <dataset ...>
        <background resource="background_id" scaleMode="eExactFit" color1="0xffffffff" color2="0xffffffff"/>
...
Is it possible to have a transparent background behind the map?

Yes. There are a couple of steps. First, ensure that the map view's opacity is deactivated.

// <!-- VgMyViewController.mm --> 
- (void)viewDidLoad
{
    [super viewDidLoad];
    ...
    //Where mMapView is the VgEAGLView object
    mMapView.opaque = NO;   
}
Second, update the data bundle's vg_config.xml file to contain a clear background color. At the same time you should deactivate or remove the tag if it's used.
// <!-- vg_config.xml -->     
...    
<datasets>
        <dataset ...>
            <background_OFF resource="eBackground16" scaleMode="eRepeat" widthInPixel="8.0" color1="0xbfbfbfff" color2="0x000000ff"/>
            <backgroundClearColor color="0x00000000"/>
...
My iOS application crashes sometimes after having made a call to a VisioDevKit method

The VisioDevKit must be called from the same thread that it's running in. Therefore if the VisioDevKit is running within the main thead, then it must also be called from the main thread.

If an input is received from within another thread (different to that of the VisioDevKit thread), then it will be necessary to foward that input on to the VisioDevKit. Below are some examples on how to achieve this.

Option 1

    dispatch_async(dispatch_get_main_queue(), ^{

    // Code to exec in main thread (assuming that the VisioDevKit is running in the main thread)

    });
Option 2
    -(void)testThread2:(NSNumber)pNumber {
    // Code to exec in main thread (assuming that the VisioDevKit is running in the main thread)
    }
    
    ...
    // Call within the non-main thread
    [self performSelectorOnMainThread:@selector(testThread2:) withObject:[NSNumber numberWithInt:2] waitUntilDone:NO];
    ...

Android

My application freezes or crashes when I try to display any GUI elements (Toast, Dialog, ...).

Android's GUI cannot be manipulated inside the GLThread. Post a new Runnable with a Handler of the main thread.

 // FIELDS
 protected Handler mHandler = null;
 
 protected void OnCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    mHandler = new Handler(Looper.myLooper());
    ...
 }
 
 ...
 mHandler.post(new Runnable() {...}); 
My application freezes or crashes when I try to use the VisioDevKit.

Our SDK must be used inside the GLThread. Queue your code inside the VgSurfaceView.

 // FIELDS
 protected VgSurfaceView mVgSurfaceView = null;
 
 protected void OnCreate(Bundle savedInstanceState) {
 super.onCreate(savedInstanceState);
 ...
 mVgView = ((VgSurfaceView) findViewById(R.id.VgSurfaceView));
 }
 
 ...
 mVgView.queueEvent(new Runnable() {...SDK code...});
My Activity runs correctly, LoadConfiguration and selectDataset returned true, but my screen remains black.

Call VgSurfaceView.resumeRendering() after selectDataset

I try to load a PNG picture using VgITextureManager::createTexture, but it freezes or crashes.

Your PNG source file might be located inside res/drawable. PNGs that will be used as Textures should be located inside res/raw. We are currently working on this issue

I try your SDK on the Android emulator, but it does not seem to run properly or very slowly.

The SDK does work with the Android emulator, however there are certain steps to be done before it will work correctly. For more information on running VisioDevKit in the emulator, see Using the Android Emulator .

What purpose does the swigReleaseOwnership() method serve?

This is a memory management method required by all java classes that inherit from any VisioDevKit object. It should be called within the constructor of the java class which is inheriting from the VisioDevKit object. It comes about from using SWIG/Director which forms the bridge betweeen the java code and VisioDevKit, which is implemented in C++.

When I run the Visioglobe sample applications on the emulator I get the following error
    JNI ERROR: NewWeakGlobalRef not implemented
    VM aborting

The VisioDevKit uses a Java Native Interface (JNI) which relies on NewWeakGlobalRef to be supported. NewWeakGlobalRef was not introduced to the emulator platform until a later version, compared to the version which is supported on the actual device. See Using the Android Emulator for more details.

Does the VisioDevKit work if I enable the hardware acceleration from within the android manifest (i.e. with the following line):
    android:hardwareAccelerated="true"

The short answer is no. Hardware acceleration on physical devices isn't currently supported by the VisioDevKit. The VisioDevKit Engine uses some particular drawing operations not currently supported by hardware accleration. We've seen issues where the GLThread isn't closed correctly between onPause and onResume events which causes the application running on certain devices to freeze and give an 'out of memory warnings'. Furthermore, we strongly suggest that in your manifest that you set the hardwardAcclerated item explicitly to "false", as some android devices enable this feature by default. Note: hardware acceleration is only avavailable to Android 3.0 (API level 11) and above.

My accented characters are not displayed correctly in my application.

Firstly, verify that the file containing the accented characters is saved in a format that supports accented characters, such as UTF-8.

If this is the case and accented characters are still not being displayed correctly AND, Eclipse is the IDE then it is possible that Eclipse is responsible for modifying the format of the file. To change Eclipses default file endcoding:

Go to Eclipse->Preferences>General>Workspace and select UTF-8 as the Text File Encoding. This will set the default encoding for all the resources in your workspace. Any components you create from now on using the default encoding should all match.

Or to change the encoding for single a resource (project, folder or file)

Right (or Control) click on the resource in the Package Explorer and select the Properties option at the bottom of the contextual menu. Go to Resource>Text File Encoding. You should see "Inherited from container (UTF-8)" if you've made the change above, otherwise it will be (MacRoman). Select Other - UTF-8 and Apply to make the warning go away.

My Android application crashes sometimes after having made a call to a VisioDevKit method

The VisioDevKit must be called from the same thread that it's running in. On Android the the VisioDevKit is running within the GL thead, so it must also be called from the GL thread.

If an input is received from within another thread (different to that of the VisioDevKit thread), then it will be necessary to foward that input on to the VisioDevKit. Below are some examples on how to achieve this.

    // Run from the main thread to execute code in the GL Thread
    mSurfaceView.queueEvent(new Runnable() 
    {
        public void run() 
        {
             // Code to exec in GL thread
        }
    });
Furthermore, the android system calls related to the UI, should be called from the UI thread.
    // Run from the GL thread to execute code in the main Thread
    runOnUiThread(new Runnable() 
    {
        public void run()
        {
            Toast.makeText(VgMyMapActivity.this, "I'm called from the UI Thread!", Toast.LENGTH_LONG).show();
        }
    });
VisioDevKit 2.0, Visioglobe® 2013