Низкая частота кадров с Irrlicht на Android - PullRequest
2 голосов
/ 01 сентября 2011

Я скомпилировал Android-порт Irrlicht из http://gitorious.org/irrlichtandroid/ и сделал приложение, чтобы просто загрузить SkyBox. Тем не менее, я получаю непредсказуемые частоты кадров. На эмуляторе fps никогда не выходит за пределы 5. На моем DELL XCD35 с eclair он обычно не превышает 10 кадров в секунду, НО, примерно в 1 из 10 запусков приложение работает хорошо при 60 кадрах в секунду. Активность настроена для полноэкранного ландшафтного режима.

Ниже приведен код, я пропустил заголовочные файлы классов, чтобы пост был коротким.

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 */

Пожалуйста, помогите !!

1 Ответ

5 голосов
/ 12 сентября 2011

Понял наконец !!

Кажется, в Android SDK есть ошибка. Когда вы пытаетесь установить горизонтальную ориентацию экрана из AndroidManifest.xml с помощью 'android: screenOrientation = "landscape"', вы получаете низкую частоту кадров в GLSurfaceView. Использование

this.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE );

в коде решил все проблемы. Мой код теперь работает с постоянной скоростью 60 кадров в секунду.

...