2011-08-31 94 views
2

我编写了一个来自http://gitorious.org/irrlichtandroid/的Irrlicht Android端口,并提出了一个应用程序来加载一个LoST SkyBox。但是,我得到不可预知的帧速率。在仿真器上,fps永远不会超过5.在带有eclair的DELL XCD35上,它通常不会超过10 fps,但是,在大约10次发射中的1次中,应用程序运行速度很快,达到60 fps。 活动配置为全屏风景模式。Android上Irrlicht的低帧速率

以下是代码,我省略了类头文件以保持文章简短。

BlueStoneActivity.java

public class BlueStoneActivity extends Activity { 
    static { 
     System.loadLibrary("irrlicht"); 
     System.loadLibrary("bluestone"); 
    } 

    GLSurfaceView glView; 

    @Override 
    public void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     this.requestWindowFeature(Window.FEATURE_NO_TITLE); 
     this.getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN); 
     glView=new GLSurfaceView(this); 
     glView.setRenderer(new IrrlichtRenderer(this)); 
     setContentView(glView); 
     Debug.startMethodTracing("bstone"); 
     nativeOnCreate(); 
    } 

    @Override 
    protected void onDestroy() { 
     nativeOnDestroy(); 
     super.onDestroy(); 
     Debug.stopMethodTracing(); 
    } 

    @Override 
    protected void onPause() { 
     super.onPause(); 
    } 

    @Override 
    protected void onResume() { 
     super.onResume(); 
    } 

    public native void nativeOnCreate(); 
    public native void nativeOnDestroy(); 
    public native void nativeOnPause(); 
    public native void nativeOnResume(); 
    public native void nativeOnResize(int w, int h); 
    public native void nativeDrawIteration(); 
} 

IrrlichtRender.java

public class IrrlichtRenderer implements Renderer { 
     BlueStoneActivity activity; 

     IrrlichtRenderer(BlueStoneActivity activity){ 
      this.activity=activity; 
     } 

     @Override 
     public void onDrawFrame(GL10 arg0) { 
      activity.nativeDrawIteration(); 
     } 

     @Override 
     public void onSurfaceChanged(GL10 gl, int width, int height) { 
      activity.nativeOnResize(width, height); 
     } 

     @Override 
     public void onSurfaceCreated(GL10 arg0, EGLConfig arg1) { 
     } 
    } 

JNI封装

#include <jni.h> 
#include <android/log.h> 
#include "EngineManager.h" 
#include "InputManager.h" 

game::EngineManager *engine; 

int importGLInit(); 
void importGLDeinit(); 

#ifndef _Included_com_devin_BlueStoneActivity 
#define _Included_com_devin_BlueStoneActivity 
#ifdef __cplusplus 
extern "C" { 
#endif 

JNIEXPORT void JNICALL Java_com_devin_BlueStoneActivity_nativeOnCreate 
    (JNIEnv *, jobject){ 
    engine=new game::EngineManager(); 
} 


JNIEXPORT void JNICALL Java_com_devin_BlueStoneActivity_nativeOnDestroy 
    (JNIEnv *, jobject){ 
    engine->device->drop(); 
    importGLDeinit(); 
} 

JNIEXPORT void JNICALL Java_com_devin_BlueStoneActivity_nativeOnResize 
    (JNIEnv *env, jobject thiz, jint width, jint height){ 
    __android_log_print(ANDROID_LOG_INFO, "NDK", "ONRESIZE - [%d %d]", width, height); 
    engine->mWidth=width; 
    engine->mHeight=height; 
    importGLInit(); 
    engine->glInit(); 
} 


JNIEXPORT void JNICALL Java_com_devin_BlueStoneActivity_nativeDrawIteration 
    (JNIEnv *, jobject){ 
    engine->drawIteration(); 
} 


JNIEXPORT void JNICALL Java_com_devin_BlueStoneActivity_nativeOnPause 
    (JNIEnv *, jobject){ 
} 


JNIEXPORT void JNICALL Java_com_devin_BlueStoneActivity_nativeOnResume 
    (JNIEnv *, jobject){ 

} 


#ifdef __cplusplus 
} 
#endif 
#endif 

EngineManager.cpp

#include <irrlicht.h> 
#include "EngineManager.h" 

namespace game { 

EngineManager::EngineManager() { 
    input=new game::InputManager(); 
    app=new game::ApplicationManager(input); 
} 

EngineManager::~EngineManager() { 
} 

void EngineManager::glInit(){ 
    device=createDevice(video::EDT_OGLES1, core::dimension2d<u32>(mWidth, mHeight), 16, false, false, false, 0); 
    driver=device->getVideoDriver(); 
    scenegraph=device->getSceneManager(); 
    guienv=device->getGUIEnvironment(); 

    app->initApp(device); 
} 

void EngineManager::drawIteration(){ 
    device->run(); 
    driver->beginScene(true, true, app->clearColor); 

    app->drawIteration(); 

    scenegraph->drawAll(); 
    guienv->drawAll(); 
    driver->endScene(); 
} 

} /* namespace game */ 

ApplicationManager.cpp

#include "ApplicationManager.h" 
#include "InputManager.h" 

namespace game { 

ApplicationManager::ApplicationManager(InputManager *in) { 
    this->input=in; 
} 

ApplicationManager::~ApplicationManager() { 
} 

void ApplicationManager::initApp(IrrlichtDevice *device){ 
    this->device=device; 
    this->driver=device->getVideoDriver(); 
    this->scenegraph=device->getSceneManager(); 
    this->guienv=device->getGUIEnvironment(); 

    // Camera setup 
    camera=scenegraph->addCameraSceneNode(); 
    camera->setPosition(core::vector3df(20.0f, 15.0f, 15.0f)); 
    camera->setTarget(core::vector3df(0.0f, 0.0f, 0.0f)); 

    // Sample objects 
    bool sceneLoaded=scenegraph->loadScene("/sdcard/BlueStone/redsky.irr"); 
    if(sceneLoaded) 
     __android_log_print(ANDROID_LOG_INFO, "NDK", "SceneLoaded"); 
    else 
     __android_log_print(ANDROID_LOG_INFO, "NDK", "SceneLoaded false"); 

    clearColor=video::SColor(255, 20, 40, 40); 
    statsText=L"START"; 
    text=guienv->addStaticText(statsText.c_str(), core::recti(50,50,50+100,50+60), true, true, 0, 18, false); 
    text->setOverrideColor(video::SColor(255, 64, 20, 20)); 
} 

void ApplicationManager::drawIteration(){ 
    statsText=L"FPS: "; 
    statsText+=driver->getFPS(); 
    text->setText(statsText.c_str()); 
} 

} /* namespace game */ 

请帮助!

回答

5

终于明白了!

看来Android SDK有一个bug。当您尝试使用'android:screenOrientation ='landscape''从AndroidManifest.xml中设置屏幕方向为横向时,您会在GLSurfaceView上获得较低的帧速率。 使用

this.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE); 

在代码中解决了所有问题。我的代码现在以一致的60fps运行。

+0

你知道一个很好的教程来设置Android平台上的Irrlicht和Bullet物理引擎吗?或者你能告诉我我需要做什么来安装它吗?请通过http://gamedev.stackexchange.com/questions/17572/how-do-you-setup-the-irrlicht-and-bullet-engines-for-android-development与我联系。 – Metropolis