Ogre 1.9 Android移植

Ogre 1.9 Android移植

分类: 图形渲染2013-02-04 16:47 3860人阅读 评论(14) 收藏 举报

Android Ogre C++linuxLinuxLINUX

上一篇博客,将1.8.1这个版本移植到了Android平台,无奈着不是官方版本,不太完美。这次尝试为Android平台构建1.9版本(注意这是个不稳定版本,1.9官方没有正式Release)。

依赖库官方已经移植好了,直接下载下来就可以了。

地址 http://sourceforge.net/projects/ogre/files/ogre-dependencies-android/1.9/AndroidDependencies.zip/download

具体的移植步骤,请看这里的官方文档,很详细了。我就说几个移植中需要注意的地方。

Android NDK我选的是官方的android-ndk-r8d,顺利的移植了,其他版本无一幸免都有无法检测编译机器类型的错误,应该是Ogre使用的android-cmake版本的问题,具体我没有细究。

环境变量ANDROID_NDK别忘了,这个是android-cmake脚本要用到的。

编译出来的,SampleOgreBrowserNDK这个安装包的resources.cfg有点小问题,我做了点修改,修改如下:

# Resources required by the sample browser and most samples.
[Essential]
APKZip=/packs/SdkTrays.zip
APKFileSystem=/thumbnails

# Common sample resources needed by many of the samples.
# Rarely used resources should be separately loaded by the
# samples which require them.
[Popular]
APKFileSystem=/fonts
APKFileSystem=/materials/programs
APKFileSystem=/materials/programs/GLSLES
APKFileSystem=/materials/scripts
APKFileSystem=/materials/textures
APKFileSystem=/materials/textures/nvidia
APKFileSystem=/models
APKFileSystem=/particle
APKFileSystem=/RTShaderLib
APKFileSystem=/RTShaderLib/materials
APKFileSystem=/RTShaderLib/GLSLES
APKFileSystem=/materials/scripts/SSAO
APKFileSystem=/materials/textures/SSAO
APKZip=/packs/cubemap.zip
APKZip=/packs/cubemapsJS.zip
APKZip=/packs/dragon.zip
APKZip=/packs/fresneldemo.zip
APKZip=/packs/ogretestmap.zip
APKZip=/packs/ogredance.zip
APKZip=/packs/Sinbad.zip
APKZip=/packs/skybox.zip

[General]
APKFileSystem=/

编译出来的库都是静态链接的,一堆依赖,稍不留神就出问题,可能本人水平不够吧。

写了个测试程序,SampleBrowser这个项目一堆#ifdef,看着真心头疼,自己写了个简单的Android测试程序。

先上代码:

//File: main.cpp

#include <OgrePlatform.h>
#include <OgreRoot.h>
#include <EGL/egl.h>
#include <GLES/gl.h>

#include <android/log.h>
#include <android_native_app_glue.h>

#ifdef OGRE_STATIC_LIB
#include <OgreStaticPluginLoader.h>
#endif

#ifdef USE_RTSHADER_SYSTEM
#   include "OgreRTShaderSystem.h"
#endif

#include "Android/OgreAPKFileSystemArchive.h"
#include "Android/OgreAPKZipArchive.h"
#include "ANDROID/OgreAndroidEGLWindow.h"

#define LOGI(...) ((void)__android_log_print(ANDROID_LOG_INFO, "Ogre", __VA_ARGS__))
#define LOGW(...) ((void)__android_log_print(ANDROID_LOG_WARN, "Ogre", __VA_ARGS__))

#ifdef OGRE_STATIC_LIB
Ogre::StaticPluginLoader* gStaticPluginLoader;
#endif

Ogre::Root* gRoot = NULL;
Ogre::RenderWindow* gWnd = NULL;
AAssetManager* gAssetMgr = NULL;
bool bInit = false;

static Ogre::DataStreamPtr openAPKFile(const Ogre::String& fileName)
{
    Ogre::DataStreamPtr stream;
    AAsset* asset = AAssetManager_open(gAssetMgr, fileName.c_str(), AASSET_MODE_BUFFER);
    if(asset) {
        off_t length = AAsset_getLength(asset);
        void* membuf = OGRE_MALLOC(length, Ogre::MEMCATEGORY_GENERAL);
        memcpy(membuf, AAsset_getBuffer(asset), length);
        AAsset_close(asset);

stream = Ogre::DataStreamPtr(new Ogre::MemoryDataStream(membuf, length, true, true));
    }

return stream;
}

static void handleCmd(struct android_app* app, int32_t cmd)
{
    switch(cmd)
    {
    case APP_CMD_INIT_WINDOW:
        if(app->window && gRoot) {
            AConfiguration* config = AConfiguration_new();
            AConfiguration_fromAssetManager(config, app->activity->assetManager);

if(!gWnd) {
                LOGW("APP_CMD_INIT_WINDOW");
                Ogre::NameValuePairList opt;
                opt["externalWindowHandle"] = Ogre::StringConverter::toString((int)app->window);
                opt["androidConfig"] = Ogre::StringConverter::toString((int)config);
                gWnd = Ogre::Root::getSingleton().createRenderWindow("OgreWindow", 0, 0, false, &opt);

if(gWnd->isFullScreen()) {
                    LOGW("Window Is Fullscreen");
                }

Ogre::Root::getSingleton().getRenderSystem()->_initRenderTargets();

// Clear event times
                            Ogre::Root::getSingleton().clearEventTimes();

LOGI("CreateSceneManager Begin");
                Ogre::SceneManager* sm = gRoot->createSceneManager(Ogre::ST_GENERIC, "DummyScene");
                LOGI("CreateSceneManager End");

Ogre::Camera* cam = sm->createCamera("DummyCamera");
                cam->setPosition(Ogre::Vector3(20, 80, 50));
                cam->lookAt(Ogre::Vector3(0, 0, 0));
                cam->setNearClipDistance(5);

Ogre::Viewport* vp = gWnd->addViewport(cam);
                vp->setBackgroundColour(Ogre::ColourValue(0.9, 0.9, 0.9));

Ogre::Real fWidth = vp->getActualWidth();
                Ogre::Real fHeight = vp->getActualHeight();
                LOGW("fWidth: %f, fHeight: %f", fWidth, fHeight);

cam->setAspectRatio(Ogre::Real(vp->getActualWidth()) / Ogre::Real(vp->getActualHeight()));

Ogre::TextureManager::getSingleton().setDefaultNumMipmaps(5);

sm->setAmbientLight(Ogre::ColourValue(0.9, 0.9, 0.9));
                sm->createLight()->setPosition(20, 80, 50);

sm->setSkyBox(true, "Examples/CloudyNoonSkyBox");
                Ogre::Entity* head = sm->createEntity("Head", "ogrehead.mesh");
                Ogre::Entity* head2 = sm->createEntity("Head2", "r5capsule.mesh");

Ogre::SceneNode* headNode = sm->getRootSceneNode()->createChildSceneNode();
                headNode->attachObject(head);
                headNode->setPosition(0, 0, 0);

Ogre::SceneNode* headNode2 = sm->getRootSceneNode()->createChildSceneNode();
                headNode2->attachObject(head2);
                headNode2->setPosition(0, 10, 0);

gWnd->windowMovedOrResized();
                bInit = true;
            }else
            {
                static_cast<Ogre::AndroidEGLWindow*>(gWnd)->_createInternalResources(app->window, config);
            }

AConfiguration_delete(config);
        }
        break;
    }
}

void android_main(struct android_app* state)
{
    app_dummy();

gAssetMgr = state->activity->assetManager;

struct android_pool_source* source;

state->onAppCmd = &handleCmd;
    gRoot = new Ogre::Root();

//#ifdef OGRE_STATIC_LIB
    LOGI("Load Plugin");
    gStaticPluginLoader = new Ogre::StaticPluginLoader();
    gStaticPluginLoader->load();
    LOGI("Load Plugin End");
//#endif
    Ogre::ArchiveManager::getSingleton().addArchiveFactory(new Ogre::APKFileSystemArchiveFactory(gAssetMgr));
    Ogre::ArchiveManager::getSingleton().addArchiveFactory(new Ogre::APKZipArchiveFactory(gAssetMgr));

gRoot->setRenderSystem(gRoot->getAvailableRenderers().at(0));
    gRoot->initialise(false);

Ogre::ConfigFile cf;
    cf.load(openAPKFile("resources.cfg"));

Ogre::ConfigFile::SectionIterator seci = cf.getSectionIterator();
    Ogre::String sec, type, arch;

while(seci.hasMoreElements()) {
        sec = seci.peekNextKey();
        Ogre::ConfigFile::SettingsMultiMap* settings = seci.getNext();
        Ogre::ConfigFile::SettingsMultiMap::iterator i;

for(i = settings->begin(); i != settings->end(); i++) {
            type = i->first;
            arch = i->second;

LOGI("arch: %s, type: %s, sec: %s", arch.c_str(), type.c_str(), sec.c_str());
            Ogre::ResourceGroupManager::getSingleton().addResourceLocation(arch, type, sec);
        }
    }

Ogre::ResourceGroupManager::getSingleton().initialiseAllResourceGroups();

while (1) {

int ident;
            int events;
            struct android_poll_source* source;

while ((ident=ALooper_pollAll(0, NULL, &events,
                    (void**)&source)) >= 0) {

// Process this event.
                if (source != NULL)
                    source->process(state, source);

if(state->destroyRequested != 0)
                    return;

}

if(gWnd != NULL && gWnd->isActive()) {
                gWnd->windowMovedOrResized();
                gRoot->renderOneFrame();
             }
    }
}

使用了NativeActivity,所以不用写一行Java代码。(NativeActivity Android NKD中有个例子,代码不明白的话可以参考一下)。接着是Android.mk

LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)

LOCAL_MODULE := andogre

LOCAL_SRC_FILES := main.cpp

LOCAL_LDLIBS := -landroid -lc -lm -ldl -llog -lEGL -lGLESv2
LOCAL_LDLIBS += -L$(MY_HOME)/android/ogre-v1-9/lib -L$(MY_HOME)/android/AndroidDependencies/lib/armeabi
LOCAL_LDLIBS += -lPlugin_ParticleFXStatic -lPlugin_OctreeSceneManagerStatic -lRenderSystem_GLES2Static
LOCAL_LDLIBS += -lOgreRTShaderSystemStatic -lOgreOverlayStatic -lOgreMainStatic
LOCAL_LDLIBS += -lzzip -lz -lFreeImage -lfreetype -lOIS $(MY_HOME)/android/systemlibs/armeabi/libsupc++.a $(MY_HOME)/android/systemlibs/armeabi/libstdc++.a D:/workspace/AndOgre/obj/local/armeabi/libcpufeatures.a

LOCAL_STATIC_LIBRARIES := android_native_app_glue cpufeatures

LOCAL_CFLAGS := -DGL_GLEXT_PROTOTYPES=1 -I$(MY_HOME)/android/ogre-v1-9/include/OGRE
LOCAL_CFLAGS += -I$(MY_HOME)/android/ogre-v1-9/include/OGRE/Android
LOCAL_CFLAGS += -I$(MY_HOME)/android/ogre-v1-9/include/OGRE/Overlay
LOCAL_CFLAGS += -I$(MY_HOME)/android/ogre-v1-9/include/OGRE/Plugins/OctreeSceneManager
LOCAL_CFLAGS += -I$(MY_HOME)/android/ogre-v1-9/include/OGRE/Plugins/ParticleFX
LOCAL_CFLAGS += -I$(MY_HOME)/android/ogre-v1-9/include/OGRE/RenderSystems/GLES2
LOCAL_CFLAGS += -I$(MY_HOME)/android/ogre-v1-9/include/OGRE/RTShaderSystem
LOCAL_CFLAGS += -ID:/android-ndk-r8d/sources/cpufeatures
LOCAL_CFLAGS += -I$(MY_HOME)/android/AndroidDependencies/include
LOCAL_CFLAGS += -I$(MY_HOME)/android/AndroidDependencies/include/OIS
LOCAL_CFLAGS += -fexceptions -frtti -x c++ -D___ANDROID___ -DANDROID -DZZIP_OMIT_CONFIG_H -DUSE_RTSHADER_SYSTEM=1
LOCAL_CFLAGS += -DOGRE_STATIC_GLES2 -DOGRE_STATIC_OctreeSceneManager -DOGRE_STATIC_ParticleFX

include $(BUILD_SHARED_LIBRARY)

$(call import-module, android/native_app_glue)
$(call import-module, android/cpufeatures)

Application.mk文件:

APP_ABI := armeabi
APP_STL := gnustl_static

为了使用NativeActivity,AndroidManifest.xml得改一下,要不然系统不能识别到NativityActivity

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="cloud.example.andogre"
    android:versionCode="1"
    android:versionName="1.0" >

<uses-sdk
        android:minSdkVersion="8"
        android:targetSdkVersion="17" />

<-- 无java代码 -->

<application android:allowBackup="true" android:label="@string/app_name" android:hasCode="false">

<-- 这里,告诉系统Activity是NativeActivity -->
        <activity android:name="android.app.NativeActivity"
                android:label="@string/app_name"
                android:configChanges="orientation|keyboardHidden"
                android:theme="@android:style/Theme.Black.NoTitleBar.Fullscreen" >
            <!-- Tell NativeActivity the name of or .so -->
            <meta-data android:name="android.app.lib_name"
                    android:value="andogre" />
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>

</manifest>

以上就是全部内容。欢迎指正

2
时间: 2025-01-04 05:14:38

Ogre 1.9 Android移植的相关文章

第5章 Android移植与驱动

第5章  Android移植与驱动 通过学习本章Android移植与驱动,知道了Android移植和驱动的关系.其中,设备驱动程序包括内核驱动程序和用户空间驱动程序.Linux系统的设备分为3类:字符设备.块设备和网络设备.除网络设备外,字符设备与块设备都被映射到Linux文件系统的文件和目录,通过文件系统的系统调用接口open().write().read().close()等函数即可访问字符设备和块设备.Android中内核的结构和标准的Linux2.6内核是基本相同的,Android在其中

第4章 Android移植环境搭建

第4章 第4章主要是介绍Android移植环境搭建,其内容包括构建Android移植环境.Bootloader介绍.Android内核与移植.构建Android移植交叉开发环境中有嵌入式交叉编译环境搭建.主机交叉编译开发环境配置.主机交叉开发环境配置包括配置控制台程序.配置TFTP服务.配置TFTP有Linux下TFTP服务配置和Windows下TFTP服务配置.NFS文件系统参数Rw :可读写的权限 Ro :只读的权限 Sync:资料同步写入到内存与硬盘中  Asyncnn :资料会先暂存于内

拇指接龙游戏从WIN32向Android移植过程问题记录(2)

本文中,在前文(1)基础上,将尽可能详细记录拇指接龙游戏从WIN32向Android移植过程后期--UI运行级调试出现的问题及可能的解决办法. 问题1 正未运行,问题就来了.忽然发现,工程左上角挂着一个大大的感叹号!请看截图: 打开工程属性对话框,观察到如下现象: 我把鼠标停留在右边的横线处,后面出现一个关键单词missing.也就是说,我们的游戏工程依赖的cocos2d-x库包jar文件丢失了!? 再打开另一处观察,发现如下: 其实,有一个重要细节在上一篇中我没有交待.此前,我使用中家的版本在

cocos2d-x 从win32到android移植的全套解决方案

引言:我们使用cocos2d-x引擎制作了一款飞行射击游戏,其中创新性地融入了手势识别功能.但是我们在移植过程中遇到了很多的问题,同时也发现网上的资料少而不全.所以在项目行将结束的时候,我们特地写了这篇文章来完整记录我们整个移植的过程,纪念我们项目的成功完成,更以此来表达对帮助过我们的人的感谢.移植过程中我们在网上得到了很多帮助,更要感谢黄杨学长在最后时刻帮助我们突破难关! 0.开发平台 系统:win8 profession 64bit IDE:vs2012 rtm, eclipse cocos

第三章:Android移植平台工具介绍读书笔记

本章主要了解了Android移植平台工具,开发板,U-Boot镜像的下载与烧写等等. 1.U-Boot镜像的下载与烧写 U-Boot镜像文件“u-boot.bin”.使用USB方式下载. 1)设置启动模式 首先安装好串口线,USB下载线,把硬件拨码开关SW1设置为USB启动模式,也就是由原来的“0000”设置为“0001”: 2)打开电源 DNW工具会显示“USB:OK” 3)通过DNW下载“USBInstaller_DDR2.bin” U-Boot启动内核的过程可以分为两个阶段,两个阶段的功能

第五章Android移植与驱动读书笔记

本章我们主要学习了Android移植与驱动的关系,设备驱动模块,Linux核心与Android驱动,以及Android驱动的HelloWord这些内容!任何一个计算机系统的运行都是系统中软硬件协作的结果,没有硬件的软件是空中楼阁,而没有软件 的硬件则只是一堆废铁.硬件是底层基础,是所有软件得以运行的平台,代码最终会落实为硬件上的组合 逻辑与时序逻辑:软件则实现了具体应用,它按照各种不同的业务需求而设计,满足了用户的需求.硬件 较固定,软件则很灵活,可以适应各种复杂多变的应用.可以说,计算机系统的

拇指接龙游戏从WIN32向Android移植过程问题记录

本文将较细致地记录下最近开发课程中的示例游戏-拇指接龙游戏在从WIN32向Android移植过程中遇到的若干问题及相应解决办法. 目前极不完整,待进一步整理. 问题1 连接真机测试运行时,在SplashScreen运行时便出现如下错误提示(log.txt): 09-16 13:28:16.525: I/GLThread(25784): sending render notification tid=1009-16 13:28:18.530: D/cocos2d-x debug info(2578

Android移植与开发

Android移植可分为两个部分:应用移植和系统移植.应用移植是指将应用程序移植到某一特定硬件平台上.由于不同硬件平台之间的差异,Android SDK API也有可能存在差异,或者将应用程序从低版本Android移植到高版本的Android上.为了保证应用程序可以在新的硬件平台上正常运行,需要对源码进行一些修改.当然,如果没有或无法获取源码,只有重新在新的平台上实现了.一般Android应用移植并不涉及驱动和HAL程序库的移植.    Android系统移植是指让Android操作系统在某一特

第3章 Android移植平台工具介绍

第3章 通过本章对开发板移植平台工具介绍,如FS_S5PC100拥有丰富的硬件资源网络接口.音频的输入输出.Video输出.串口.红外接口.温度传感器.HDMI接口.VGA接口等.知道了开发板一些基本硬件组成,同时开发板FS_S5PC100软件资源有Android2.1系统源代码.Linux2.6.29 系统源代码.外设接口测试源代码和U-Boot(支持USB.网络通信).接下来说明FS_S5PC100开发平台的Android摄像头功能展示.VGA 720p高清播放功能和HDMI 720P显示功