【问题标题】:Integrating jpct-ae to Qualcomm's Vuforia engine in android在android中将jpct-ae集成到高通的Vuforia引擎
【发布时间】:2013-02-18 10:02:31
【问题描述】:

在 Android 中,我正在尝试使用本教程将 JPCT 集成到 Vuforia: http://www.jpct.net/wiki/index.php/Integrating_JPCT-AE_with_Vuforia

应用程序第一次启动时,它可以工作,但是当我返回并再次触摸“播放”时,它崩溃了。

这些是应用程序崩溃时我的 LogCat 中的错误:

FATAL EXCEPTION: main
java.lang.RuntimeException: [ 1362671862690 ] - ERROR:  A texture with the name  'texture' has been declared twice!
at com.threed.jpct.Logger.log(Logger.java:189)
at com.threed.jpct.TextureManager.addTexture(TextureManager.java:138)
at com.qualcomm.QCARSamples.ImageTargets.ImageTargetsRenderer.<init>    (ImageTargetsRenderer.java:78)
at     com.qualcomm.QCARSamples.ImageTargets.ImageTargets.initApplicationAR(ImageTargets.java:807)
at com.qualcomm.QCARSamples.ImageTargets.ImageTargets.updateApplicationStatus(ImageTargets.java:649)
at com.qualcomm.QCARSamples.ImageTargets.ImageTargets.updateApplicationStatus(ImageTargets.java:641)
at com.qualcomm.QCARSamples.ImageTargets.ImageTargets.access$3(ImageTargets.java:598)
at com.qualcomm.QCARSamples.ImageTargets.ImageTargets$InitQCARTask.onPostExecute(ImageTargets.java:226)
at com.qualcomm.QCARSamples.ImageTargets.ImageTargets$InitQCARTask.onPostExecute(ImageTargets.java:1)
at android.os.AsyncTask.finish(AsyncTask.java:417)
at android.os.AsyncTask.access$300(AsyncTask.java:127)
at android.os.AsyncTask$InternalHandler.handleMessage(AsyncTask.java:429)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:123)
at android.app.ActivityThread.main(ActivityThread.java:3691)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:507)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:847)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:605)
at dalvik.system.NativeStart.main(Native Method)

这是 Imagetargetsrenderer.java 代码

public class ImageTargetsRenderer implements GLSurfaceView.Renderer
{
public boolean mIsActive = false;

/** Reference to main activity **/
public ImageTargets mActivity;

/** Native function for initializing the renderer. */
public native void initRendering();

/** Native function to update the renderer. */
public native void updateRendering(int width, int height);

private World world=null;
private Light sun = null;
private Object3D cube = null;
private FrameBuffer fb = null;
private float[] modelViewMat=null;
private Camera cam=null;
private float fov=0;
private float fovy=0;

//private Camera cam=null;
private Object3D plane=null;

public ImageTargetsRenderer(ImageTargets activity){
    this.mActivity = activity;
    world = new World();
world.setAmbientLight(20, 20, 20);

sun = new Light(world);
sun.setIntensity(250, 250, 250);

// Create a texture out of the icon...:-)
Texture texture = new Texture(BitmapHelper.rescale(BitmapHelper.convert(mActivity.getResources().getDrawable(R.drawable.ic_launcher)), 64, 64));
TextureManager.getInstance().addTexture("texture", texture);

cube = Primitives.getCube(10);
cube.calcTextureWrapSpherical();
cube.setTexture("texture");
cube.strip();
cube.build();

world.addObject(cube);

 cam = world.getCamera();
/*cam.moveCamera(Camera.CAMERA_MOVEOUT, 50);
cam.lookAt(cube.getTransformedCenter());*/

SimpleVector sv = new SimpleVector();
SimpleVector position=new SimpleVector();
position.x=0;
position.y=0;
position.z=-10;

cube.setOrigin(position);
sv.set(cube.getTransformedCenter());
sv.y -= 100;
sv.z -= 100;

sun.setPosition(sv);
MemoryHelper.compact();

}




/** Called when the surface is created or recreated. */
public void onSurfaceCreated(GL10 gl, EGLConfig config)
{
    DebugLog.LOGD("GLRenderer::onSurfaceCreated");

    // Call native function to initialize rendering:
    initRendering();

    // Call QCAR function to (re)initialize rendering after first use
    // or after OpenGL ES context was lost (e.g. after onPause/onResume):
    QCAR.onSurfaceCreated();
}


/** Called when the surface changed size. */
public void onSurfaceChanged(GL10 gl, int width, int height)
{
    DebugLog.LOGD("GLRenderer::onSurfaceChanged");

    // Call native function to update rendering when render surface
    // parameters have changed:
    updateRendering(width, height);

    // Call QCAR function to handle render surface size changes:
    QCAR.onSurfaceChanged(width, height);

    if (fb != null) {
        fb.dispose();
   }
   fb = new FrameBuffer(width, height);
}


/** The native render function. */
public native void renderFrame();


/** Called to draw the current frame. */
public void onDrawFrame(GL10 gl)
{
    if (!mIsActive)
        return;

    // Update render view (projection matrix and viewport) if needed:
    mActivity.updateRenderView();

    //updateCamera();

    // Call our native function to render content

    renderFrame();

    world.renderScene(fb);

    world.draw(fb);

    fb.display(); 

}

public void updateModelviewMatrix(float mat[]) {
    modelViewMat = mat;
}

public void setFov(float fov_) {
    fov = fov_;
}

public void setFovy(float fovy_) {
    fovy = fovy_;
}

public void updateCamera() {
    Matrix m = new Matrix();
    m.setDump(modelViewMat);
        cam.setBack(m);
        cam.setFOV(fov);
        cam.setYFOV(fovy);

}

}

imagetargets.cpp 的代码

JNIEXPORT void JNICALL
Java_com_qualcomm_QCARSamples_ImageTargets_ImageTargetsRenderer_renderFrame(JNIEnv  *env, jobject obj)
{

const QCAR::CameraCalibration& cameraCalibration =       QCAR::CameraDevice::getInstance().getCameraCalibration();
QCAR::Vec2F size = cameraCalibration.getSize();
QCAR::Vec2F focalLength = cameraCalibration.getFocalLength();
float fovyRadians = 2 * atan(0.5f * size.data[1] / focalLength.data[1]);
float fovRadians = 2 * atan(0.5f * size.data[0] / focalLength.data[0]);

jclass activityClass = env->GetObjectClass(obj);
jfloatArray modelviewArray = env->NewFloatArray(16);
jmethodID updateMatrixMethod = env->GetMethodID(activityClass, "updateModelviewMatrix",    "([F)V");

jmethodID fovMethod = env->GetMethodID(activityClass, "setFov", "(F)V");
jmethodID fovyMethod = env->GetMethodID(activityClass, "setFovy", "(F)V");

// test
jclass newClass = env->GetObjectClass(obj);
jmethodID updateCameraMethod = env->GetMethodID(newClass, "updateCamera", "()V");

// Clear color and depth buffer 
//glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
// Get the state from QCAR and mark the beginning of a rendering section
QCAR::State state = QCAR::Renderer::getInstance().begin();
// Explicitly render the Video Background
QCAR::Renderer::getInstance().drawVideoBackground();
// Did we find any trackables this frame?
for(int tIdx = 0; tIdx < state.getNumTrackableResults(); tIdx++)
{
    // Get the trackable:
    const QCAR::TrackableResult* result = state.getTrackableResult(tIdx);
    const QCAR::Trackable& trackable = result->getTrackable();
    QCAR::Matrix44F modelViewMatrix = QCAR::Tool::convertPose2GLMatrix(result-  >getPose());
}
QCAR::Renderer::getInstance().end();


for(int tIdx = 0; tIdx < state.getNumTrackableResults(); tIdx++)
{
// Get the trackable:
const QCAR::TrackableResult* result = state.getTrackableResult(tIdx);
const QCAR::Trackable& trackable = result->getTrackable();
QCAR::Matrix44F modelViewMatrix = QCAR::Tool::convertPose2GLMatrix(result-    >getPose());

    SampleUtils::rotatePoseMatrix(180.0f, 1.0f, 0, 0, &modelViewMatrix.data[0]);
    // Passes the model view matrix to java
    env->SetFloatArrayRegion(modelviewArray, 0, 16, modelViewMatrix.data);
    env->CallVoidMethod(obj, updateMatrixMethod , modelviewArray);
    env->CallVoidMethod(obj, updateCameraMethod);
    env->CallVoidMethod(obj, fovMethod, fovRadians);
    env->CallVoidMethod(obj, fovyMethod, fovyRadians);




}
env->DeleteLocalRef(modelviewArray);



}

这个异常是什么意思?

【问题讨论】:

  • 你得到什么错误?
  • 应用程序失败。程序可以编译,但应用程序在启动时停止
  • 当你的 Logcat 失败时,你能看到任何东西吗?
  • 是的,我看到无法加载库 libQCAR.so 无法加载库 libImageTargets.so”但 .jar 在引用的库中。然后我有这样的错误:“致命异常: main java.lang.UnsatisfiedLinkError: getOpenGlEsVersionNative at com.qualcomm.QCARSamples.ImageTargets.ImageTargets.getOpenGlEsVersionNative(Native Method) at com.qualcomm.QCARSamples.ImageTargets.ImageTargets.getInitializationFlags(ImageTargets.java:384)"
  • 顺便说一句,从您的代码中,您缺少一行。我会添加一个答案。

标签: android c++ java-native-interface vuforia jpct


【解决方案1】:

将此添加到渲染器以删除加载的纹理

public void cleanup()
{
    TextureManager.getInstance().removeTexture("texture");
}

在关闭/暂停时从 Activity 调用它

protected void onPause()
{
   mRenderer.cleanup();
}

【讨论】:

    【解决方案2】:

    为了在应用矩阵之前看到一些东西,你必须首先告诉相机看对象。

    Camera cam = world.getCamera();
    cam.moveCamera(Camera.CAMERA_MOVEOUT, 50);
    cam.lookAt(cube.getTransformedCenter());
    

    请注意,当您使用标记中的模型视图矩阵更新相机时,您应该删除这些线。

    如果您按照我的教程进行操作,您实际上不必激活任何 OpenGL 状态来查看标记上方的内容(尽管出于其他原因,您可能有兴趣按照 Sam Rad 的建议激活它们)。

    【讨论】:

    • 顺便说一句,我看到教程有一些错误,比如省略了 Sam Rad 告诉你的那些行。我会尽快解决的。
    • 让Native代码调用updateCamera()函数。您不需要在 Java 中显式调用它。
    • 我指的是相同的。但是updateCamera 仅在视线中有可跟踪对象时才有效。否则 mat 为空。您可以从 for(int tIdx = 0; tIdx &lt; state.getNumActiveTrackables(); tIdx++) 中的本机代码调用它。
    • 好的,在您的构造函数中,您正在初始化一个与作为字段的对象不同的 Cam 对象。使用 cam = World.getCamera() 而不是 Camera cam = World.getCamera()。
    • @Amourreux 确保在创建立方体时不要对立方体应用任何平移或旋转
    【解决方案3】:

    ImageTarget.cpprenderFrame 方法的开头应该是这样的:

    jclass activityClass = env->GetObjectClass(obj);
    jfloatArray modelviewArray = env->NewFloatArray(16);
    jmethodID method = env->GetMethodID(activityClass, "updateModelviewMatrix", "([F)V");
    

    我认为,这将解决您的错误,因为 activityClass 未在此范围内声明

    注释掉这一行并再次测试。你不再需要它了。

    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    

    我还建议注释掉onDrawFrame() 中的renderFrame() 方法,以查看如果QCAR 没有提前开始渲染,jPCT 是否可以渲染立方体。 (仅用于测试目的)

    更不用说,QCAR 最初默认更改 OpenGL 状态。因此,您必须启用其中一些才能使用 jPCT 进行渲染。更多信息请查看OpenGL State Changes in Video Background Renderer

    onDrawFrame 中调用renderFrame 后,我将其用于OpenGL ES 1.x

    GL11 gl11 = (GL11) gl;
    gl11.glEnable(GL11.GL_DEPTH_TEST);
    gl11.glEnable(GL11.GL_CULL_FACE);
    gl11.glTexEnvi(GL11.GL_TEXTURE_ENV, GL11.GL_TEXTURE_ENV_MODE, GL11.GL_MODULATE);
    gl11.glEnable(GL11.GL_LIGHTING);
    gl11.glEnable(GL11.GL_BLEND);
    

    【讨论】:

    • 谢谢,这个错误已解决。应用程序编译但我在标记上看不到立方体(我看不到茶壶了,但这很正常)。正如我所说,在教程的第一部分中,在更改 imagetargets.cpp 之前,立方体应该出现在屏幕上,但它没有出现。也许我在java代码中有一个错误,但我看不到哪里。
    • 我已经用我在 imagetargets 和 logcat 中的新代码编辑了这个问题
    • ok :) 我已经评论了这一行,但它并没有改变任何东西。
    • @Amourreux,哪个教程?您在发送到 Java 之前是否旋转了矩阵?
    • @Amourreux,对不起,我已经有一年没碰过我的代码了。你有bitbucket的账号吗?我可以授予访问代码的权限。
    猜你喜欢
    • 2013-04-04
    • 1970-01-01
    • 1970-01-01
    • 2012-12-16
    • 1970-01-01
    • 1970-01-01
    • 2016-02-04
    • 2013-02-24
    • 1970-01-01
    相关资源
    最近更新 更多