从零开始搭建安卓EasyAr环境(三) 识别成功后的回调

接着上一篇说,集成完成之后,你打开项目中Jni目录,你会看到这几个文件
从零开始搭建安卓EasyAr环境(三) 识别成功后的回调_第1张图片

重点是helloar.cc 这个文件,我们看它的代码

void HelloAR::render()
{
    glClearColor(0.f, 0.f, 0.f, 1.f);
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

    Frame frame = augmenter_.newFrame();
    if(view_size[0] > 0){
        AR::resizeGL(view_size[0], view_size[1]);
        if(camera_ && camera_.isOpened())
            view_size[0] = -1;
    }
    augmenter_.setViewPort(viewport_);
    augmenter_.drawVideoBackground();
    glViewport(viewport_[0], viewport_[1], viewport_[2], viewport_[3]);

    for (int i = 0; i < frame.targets().size(); ++i) {
        AugmentedTarget::Status status = frame.targets()[i].status();
        if (status == AugmentedTarget::kTargetStatusTracked) {
            //这里就是说明,已经识别到了,开始绘制方块的地方
            Matrix44F projectionMatrix = getProjectionGL(camera_.cameraCalibration(), 0.2f, 500.f);
            Matrix44F cameraview = getPoseGL(frame.targets()[i].pose());
            ImageTarget target = frame.targets()[i].target().cast_dynamic();
            renderer.render(projectionMatrix, cameraview, target.size());
        }
    }
}

helloar.cc中的这个方法就是相当于识别图片的一个方法,那么我们如何在识别成功后,做自己的事情呢?我们需要将其绘制方块的代码去掉,然后在改一些地方(注意,传统JNI调用Java方法,如 env->findClass…. env->getStaticMethodId() 之类的在这里不能使用),我们需要按照接下来的步骤来做。

  1. 更改MainActivity中的nativeRender()方法,让其返回值是String
   public static native String nativeRender();

2.更改helloar.cc文件,Jni方法返回值,需要改为jstring

JNIEXPORT jstring JNICALL JNIFUNCTION_NATIVE(nativeRender(JNIEnv* env, jobject obj));

在下面找到Jni的具体实现方法,改为

JNIEXPORT jstring JNICALL JNIFUNCTION_NATIVE(nativeRender(JNIEnv* env, jobject))
{


     return env->NewStringUTF(ar.render());
}

3.更改helloar.cc文件中的HelloAr类中的render()方法,将其返回值改为 const char*

class HelloAR : public AR
{
public:
    HelloAR();
    virtual void initGL();
    virtual void resizeGL(int width, int height);
    virtual const char* render();

private:
    Vec2I view_size;
    Renderer renderer;
};

往下拉,改实现方法
 const char*  HelloAR::render()
{
    glClearColor(0.f, 0.f, 0.f, 1.f);
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

    Frame frame = augmenter_.newFrame();
    if(view_size[0] > 0){
        AR::resizeGL(view_size[0], view_size[1]);
        if(camera_ && camera_.isOpened())
            view_size[0] = -1;
    }
    augmenter_.setViewPort(viewport_);
    augmenter_.drawVideoBackground();
    glViewport(viewport_[0], viewport_[1], viewport_[2], viewport_[3]);
    const char *p="n";
    for (int i = 0; i < frame.targets().size(); ++i) {
        AugmentedTarget::Status status = frame.targets()[i].status();
        if (status == AugmentedTarget::kTargetStatusTracked) {

            const char* c_s= frame.targets()[i].target().name();
            return   c_s ;
        }else
        {
             return p;
        }
    }
    return p;
}

这里只有一点说明rame.targets()[i].target().name() 方法,得到的是你json文件配置的name值,如:
从零开始搭建安卓EasyAr环境(三) 识别成功后的回调_第2张图片
当然你也可以rame.targets()[i].target().uid(); 得到uid属性(前提是你json文件配置了这个属性)。然后我return了回去,它会回调Renderer类中的onDrawFrame方法。

4.更改ar.cc文件,ctrl+f找到 render 方法,将其返回值改成 const char*

5.更改ar.hpp文件,ctrl+f找到render方法,将其返回值改成const char*

6.更改 renderer.cc 和 renderer.hpp 文件,同上

7.最后一步更改Renderer类

public class Renderer implements GLSurfaceView.Renderer {


    public void onSurfaceCreated(GL10 gl, EGLConfig config) {
        ArScannerFragment.nativeInitGL();
    }

    public void onSurfaceChanged(GL10 gl, int w, int h) {
        ArScannerFragment.nativeResizeGL(w, h);
    }
    //更改这个方法
    public void onDrawFrame(GL10 gl) {
        String bo = null;
        try {
            bo = new String(ArScannerFragment.nativeRender().getBytes(),"UTF-8");
            if(!"n".equals(bo))
            {
                //是否正在暂用
                if(!isEnable)
                {
                    isEnable = true;
                    EasyAR.onPause();
                   mCallBack.scannerFished(bo);

                }else
                {
                    //否则不打开

                }
            }
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }

    }
}
  • onDrawFrame 这个方法,你可以简单理解为 识别成功后的回调方法,你可以在这里去写你的逻辑,比如,展示些你的模型。
  • 之前在MainActivity中,我已经将nativeRender的返回值改为我String,所以这里我要用String去接收其返回值。

额外知识

1. 识别成功后,我想展示一个自己的模型?
说明:
我并不推荐你根据官方的方法去替换模型文件,我们只需要这个EasyAr提供扫描结果,然后将结果传给我们,之后由我们自己处理,比如我想展示一个模型,加载一个网页,一个View之类的。

如何做?
1. 如果你想展示模型,你需要下载jpct-ae库,它是安卓平台下的游戏引擎库,我们用它加载3d模型,我们下载它,然后解压,将其的lib引入到你的项目中。

  1. 之后进入其代码目录下,找到HelloWord.java文件,复制到你的项目中,之后怎么调用它,就是在你识别成功后,直接调用这个类就行了。
    从零开始搭建安卓EasyAr环境(三) 识别成功后的回调_第3张图片

我用了Jpct-ae,但是背景如何透明啊?

// 类似java.awt.*中的Color类
    private RGBColor back = new RGBColor(0, 0, 0); //这里指定alpha值为0
    private View bottom;
    private float touchTurn = 0.0f;
    private float touchTurnUp = 0.0f;
    // private float touchDown = 0;
    //
    // private float baseValue = 0;
    // private float baseCameraValue = 100;
    // private float scale = 0;

    private float xpos = -1;
    private float ypos = -1;
    private Object3D cube = null;// 3d模型对象
    // 每秒帧数
    private int fps = 0;
    // 光照类
    private Light sun = null;

    private Light moon = null;
    private ProgressDialog progressDialog;

    protected void onCreate(Bundle savedInstanceState) {

        progressDialog = new ProgressDialog(this);
        progressDialog.setMessage("加载中,请稍候...");
        progressDialog.show();
        // Logger类中 jPCT中一个普通的用于打印和存储消息,错误和警告的日志类。
        // 每一个JPCT生成的消息将被加入到这个类的队列中
        Logger.log("onCreate");
        // 如果本类对象不为NULL,将从Object中所有属性装入该类
        if (master != null) {
            copy(master);
        }
        super.onCreate(savedInstanceState);
        mGLView = new GLSurfaceView(getApplication());
        // 使用自己实现的 EGLConfigChooser,该实现必须在setRenderer(renderer)之前
        // 如果没有setEGLConfigChooser方法被调用,则默认情况下,视图将选择一个与当前android.view.Surface兼容至少16位深度缓冲深度EGLConfig。

        //然后这里
          mGLView.setZOrderOnTop(true);
        mGLView.setEGLConfigChooser(8, 8, 8, 8, 16, 0);
        mGLView.getHolder().setFormat(PixelFormat.TRANSLUCENT);

这样,你就完成了展示自己的模型了(模型的更改,在这个类中,通过R.raw指定,你可以替换为自己的模型)。

下一篇我们说,如何动态的加载识别图片,而不是固定。

你可能感兴趣的:(Ar)