waldogod
Topic Author
Posts: 4
Joined: 08 Oct 2017, 12:45

Native SDK (C++) v2.0.2f2 - Android GL ES example missing definitions

11 Oct 2017, 11:29

Hi,

I am trying to evaluate NoesisGUI on Android.

I've downloaded the Native SDK (C++) v2.0.2f2 and I believe I'm missing the Android include files.

I'm looking at the Android example located here:
https://github.com/Noesis/Tutorials/tre ... loTriangle

The build files are looking for a folder I don't have:
LOCAL_EXPORT_C_INCLUDES := ../NoesisGUI-android/Include

Currently getting a compiled time error due to undefined types (like RenderCommands) which are not defined in the Native SDK includes I have.

Somewhat related, I was also missing the libNoesis.so libraries for each of the ABIs. But I found them in the Managed SDK (C#) download file.

Suggestions on what I might be missing is appreciated,

W
 
waldogod
Topic Author
Posts: 4
Joined: 08 Oct 2017, 12:45

Re: Native SDK (C++) v2.0.2f2 - Android GL ES example missing definitions

13 Oct 2017, 09:03

I've found my answer so I thought I'd update this post incase someone else is also trying to evaluate NoesisGUI and is running into problems building a Native Android example.

Aparently the example code here is 3 years old:
https://github.com/Noesis/Tutorials/tre ... loTriangle

So it must have used a previous version of the IRender and IView interfaces. Unfortunately that code is also the code in the NoesisGUI Integration tutorial so the Android integration examples you have in this doc are also outdated:
https://www.noesisengine.com/docs/Gui.C ... Guide.html

The best you can do, is look at the open gl example here:
NoesisGUI-NativeSDK-2.0.2f2\Src\Samples\GL
Which fortunately follows what's documented in he Rendering Architecture Tutorial:
https://www.noesisengine.com/docs/Gui.C ... orial.html

Which does appear to apply to the current NoesisGUI 2.X implmentation of IRender and IView.

Also you can find an Android GLES2 RenderDevice under:
NoesisGUI-NativeSDK-2.0.2f2\Src\Samples\Common\Renderers\GL

So basically the pieces are there to build a Native Android example, although there doesn't appear to be one available.
 
User avatar
jsantos
Site Admin
Posts: 2920
Joined: 20 Jan 2012, 17:18
Contact:

Re: Native SDK (C++) v2.0.2f2 - Android GL ES example missing definitions

13 Oct 2017, 19:16

Android binaries are missing from the latest C++ SDK, we will upload it again and update the integration sample. As you discovered you need to use the new API, it should be straightforward following the desktop GL integration sample.

Thanks a lot for your feedback!
 
User avatar
jsantos
Site Admin
Posts: 2920
Joined: 20 Jan 2012, 17:18
Contact:

Re: Native SDK (C++) v2.0.2f2 - Android GL ES example missing definitions

13 Oct 2017, 21:46

Please, download C++ SDK again, we have included missing binaries (x86 and arm) for android. We will update the integration sample next.
 
waldogod
Topic Author
Posts: 4
Joined: 08 Oct 2017, 12:45

Re: Native SDK (C++) v2.0.2f2 - Android GL ES example missing definitions

16 Oct 2017, 06:43

Thank you for the quick update to the C++ SDKs. And updating the GL Integration example would be awesome. However, if you could share the previous reference Android Resource Providers they would help, even if the example wasn't available.
 
User avatar
sfernandez
Site Admin
Posts: 1928
Joined: 22 Dec 2011, 19:20

Re: Native SDK (C++) v2.0.2f2 - Android GL ES example missing definitions

18 Oct 2017, 00:24

If you mean the AndroidResourceProvider from NoesisGUI 1.2, it was using the AAssetManager API available through Android NDK. It also worked when OBB files were specified.

Here is the code that can be easily adapted to work with NoesisGUI 2 provider architecture:
#ifndef __RESOURCE_ANDROIDRESOURCEPROVIDER_H__
#define __RESOURCE_ANDROIDRESOURCEPROVIDER_H__


#include <Noesis.h>
#include <NsResource/AndroidResourceProviderApi.h>
#include <NsResource/ResourceProvider.h>


// Forward declarations
//@{
struct AAssetManager;
//@}

namespace Noesis
{
namespace Resource
{

#ifdef NS_COMPILER_MSVC
#pragma warning(push)
#pragma warning(disable: 4251 4275)
#endif

////////////////////////////////////////////////////////////////////////////////////////////////////
/// Provider of resources stored inside an .apk or .obb Android file
////////////////////////////////////////////////////////////////////////////////////////////////////
class NS_RESOURCE_ANDROIDRESOURCEPROVIDER_API AndroidResourceProvider: public ResourceProvider
{
public:
    AndroidResourceProvider(AAssetManager* assetManager, const NsChar* dataPath,
        const NsChar* obbFile);
    ~AndroidResourceProvider();

private:
    Ptr<Core::IStream> RequestFile(const NsChar* name);

private:
    AAssetManager* mAssetManager;
    void* mObbHandle;
    NsString mDataPath;
};

#ifdef NS_COMPILER_MSVC
#pragma warning(pop)
#endif

}
}


#endif
#include <NsResource/AndroidResourceProvider.h>

#ifdef NS_PLATFORM_ANDROID

#include <NsCore/IStream.h>
#include <NsCore/ReflectionImplement.h>

#include <android/asset_manager.h>
#include <android/log.h>
#include "unzip.h"

#define LOGI(...) ((void)__android_log_print(ANDROID_LOG_INFO, "Noesis", __VA_ARGS__))


using namespace Noesis;
using namespace Noesis::Core;
using namespace Noesis::Resource;


namespace Noesis
{
namespace Resource
{

////////////////////////////////////////////////////////////////////////////////////////////////////
class AndroidFile : public BaseComponent, public IStream
{
public:
    AndroidFile(AAsset* asset) : mAsset(asset)
    {
    }

    ~AndroidFile()
    {
        Close();
    }

    /// From IStream
    //@{
    NsBool CanSeek() const
    {
        return true;
    }

    void SetPosition(NsSize pos)
    {
        if (AAsset_seek(mAsset, pos, SEEK_SET) < 0)
        {
            NS_ERROR("Can't seek to the specified position");
        }
    }

    NsSize GetPosition() const
    {
        off_t pos = AAsset_seek(mAsset, 0, SEEK_CUR);
        if (pos < 0)
        {
            NS_ERROR("Can't get current position");
        }

        return pos;
    }

    void SetLength(NsSize length)
    {
        NS_ERROR("Can't set stream length");
    }

    NsSize GetLength() const
    {
        return AAsset_getLength(mAsset);
    }

    NsBool CanRead() const
    {
        return true;
    }

    void Read(void* buffer, NsSize size)
    {
        int readBytes = AAsset_read(mAsset, buffer, size);
        if (readBytes < 0 || static_cast<NsSize>(readBytes) < size)
        {
            NS_ERROR("Can't read specified bytes");
        }
    }

    NsBool CanWrite() const
    {
        return false;
    }

    void Write(const void* buffer, NsSize size)
    {
        NS_ERROR("Can't write to stream");
    }

    void Flush()
    {
    }

    void Close()
    {
        AAsset_close(mAsset);
    }
    //@}

private:
    AAsset* mAsset;

    NS_IMPLEMENT_INLINE_REFLECTION(AndroidFile, BaseComponent)
    {
        NsImpl<IStream>();
    }
};

////////////////////////////////////////////////////////////////////////////////////////////////////
class ObbFile : public BaseComponent, public IStream
{
public:
    ObbFile(void* obbHandle, const unz_file_info& info) : mBuffer(0), mSize(info.uncompressed_size),
        mPosition(0)
    {
        mBuffer = new NsByte[mSize];

        int readBytes = unzReadCurrentFile(obbHandle, mBuffer, mSize);
        if (readBytes < 0 || static_cast<NsSize>(readBytes) < mSize)
        {
            LOGI("Unable to read all data from OBB");
            NS_ERROR("Unable to read all data from OBB");
        }

        unzCloseCurrentFile(obbHandle);
    }

    ~ObbFile()
    {
        Close();
    }

    /// From IStream
    //@{
    NsBool CanSeek() const
    {
        return true;
    }

    void SetPosition(NsSize pos)
    {
        if (pos > mSize)
        {
            NS_ERROR("Can't set stream position");
        }

        mPosition = pos;
    }

    NsSize GetPosition() const
    {
        return mPosition;
    }

    void SetLength(NsSize length)
    {
        NS_ERROR("Can't set stream length");
    }

    NsSize GetLength() const
    {
        return mSize;
    }

    NsBool CanRead() const
    {
        return true;
    }

    void Read(void* buffer, NsSize size)
    {
        if (mPosition + size > mSize)
        {
            NS_ERROR("Can't read specified bytes");
        }

        memcpy(buffer, &mBuffer[mPosition], size);
        mPosition += size;
    }

    NsBool CanWrite() const
    {
        return false;
    }

    void Write(const void* buffer, NsSize size)
    {
        NS_ERROR("Can't write to stream");
    }

    void Flush()
    {
    }

    void Close()
    {
        delete[] mBuffer;
        mSize = 0;
        mPosition = 0;
    }
    //@}

private:
    NsByte* mBuffer;
    NsSize mSize;
    NsSize mPosition;

    NS_IMPLEMENT_INLINE_REFLECTION(ObbFile, BaseComponent)
    {
        NsImpl<IStream>();
    }
};

}
}

////////////////////////////////////////////////////////////////////////////////////////////////////
AndroidResourceProvider::AndroidResourceProvider(AAssetManager* assetManager,
    const NsChar* dataPath, const NsChar* obbFile) : mAssetManager(assetManager), mObbHandle(0),
    mDataPath(dataPath)
{
    if (String::FindLast(obbFile, ".obb") > 0)
    {
        LOGI("Using OBB File");

        // Extract obb file name from StreamingAssets path
        NsInt start = String::FindFirst(obbFile, "/", 0);
        if (start < 0)
        {
            start = 0;
        }
        NsInt end = String::FindLast(obbFile, "!", 0);
        if (end < 0)
        {
            end = String::Length(obbFile);
        }

        NsString obb(&obbFile[start], end - start);

        LOGI("OBB = %s", obbFile);

        mObbHandle = unzOpen(obb.c_str());
        if (mObbHandle == 0)
        {
            NS_ERROR("Unable to open OBB file '%s'", obb.c_str());
        }

        mDataPath = "assets/";
        mDataPath += dataPath;
    }
}

////////////////////////////////////////////////////////////////////////////////////////////////////
AndroidResourceProvider::~AndroidResourceProvider()
{
    if (mObbHandle != 0)
    {
        unzClose(mObbHandle);
    }
}

////////////////////////////////////////////////////////////////////////////////////////////////////
Ptr<IStream> AndroidResourceProvider::RequestFile(const NsChar* name)
{
    NsString assetPath = mDataPath + name;
    LOGI("RequestFile(%s)", assetPath.c_str());

    if (mObbHandle != 0)
    {
        if (unzLocateFile(mObbHandle, assetPath.c_str(), 1) == UNZ_OK)
        {
            unz_file_info info;
            if (unzGetCurrentFileInfo(mObbHandle, &info, 0, 0, 0, 0, 0, 0) == UNZ_OK)
            {
                if (unzOpenCurrentFile(mObbHandle) == UNZ_OK)
                {
                    LOGI("Creating ObbFile Stream [%u]", (unsigned int)info.uncompressed_size);
                    return *new ObbFile(mObbHandle, info);
                }
            }
        }
    }
    else
    {
        NS_ASSERT(mAssetManager);
        AAsset* asset = AAssetManager_open(mAssetManager, assetPath.c_str(), AASSET_MODE_STREAMING);
        if (asset != 0)
        {
            return *new AndroidFile(asset);
        }
    }

    return Ptr<IStream>::Null();
}

#endif
Anyway, in order to update the Android integration sample we will have to implement the same provider.

Who is online

Users browsing this forum: Google [Bot] and 3 guests