效果简直了,但代码架构有点坑,慢慢道来。


libc++_shared.so应该是c++的库;libARWrapperNativeCaresExample.so也有对应的c++文件;那么,libARWrapper.so从哪里来?下一章节讲。


ARSimpleNativeCarsActivity

Java层的封装,注意ARActivity。

public abstract class ARActivity extends Activity implements CameraEventListener {}

public class ARSimpleNativeCarsActivity extends ARActivity {

    private SimpleNativeRenderer simpleNativeRenderer = new SimpleNativeRenderer();

    @Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState); setContentView(R.layout.main);
} public void onStop() {
SimpleNativeRenderer.demoShutdown(); super.onStop();
} @Override
protected ARRenderer supplyRenderer() {  // ARACTIVITY到底是何方神圣?它的设计理念是什么?
return simpleNativeRenderer;
} @Override
protected FrameLayout supplyFrameLayout() {
return (FrameLayout) this.findViewById(R.id.mainLayout); }
}

[ARActivity] 的理解很重要!不过,先来看 [SimpleNativeRenderer]。 <-- 【一对好兄弟!】
public class SimpleNativeRenderer extends ARRenderer {    // 重在实现 ARRenderer 的接口

    // Load the native libraries.
static {
System.loadLibrary("c++_shared");
System.loadLibrary("ARWrapper");
System.loadLibrary("ARWrapperNativeCarsExample");
} private FPSCounter counter = new FPSCounter();

/****************************************************************/
public static native void demoInitialise(); public static native void demoShutdown();  // --> 在哪里用到了呢? public static native void demoSurfaceCreated(); public static native void demoSurfaceChanged(int w, int h); public static native void demoDrawFrame();

/****************************************************************/
/**
* By overriding {@link #configureARScene}, the markers and other settings can be configured
* after the native library is initialised, but prior to the rendering actually starting.
* Note that this does not run on the OpenGL thread. Use onSurfaceCreated/demoSurfaceCreated
* to do OpenGL initialisation.
*/
@Override
public boolean configureARScene() {
SimpleNativeRenderer.demoInitialise();
return true;
} @Override
public void onSurfaceChanged(GL10 gl, int w, int h) {
super.onSurfaceChanged(gl, w, h);
SimpleNativeRenderer.demoSurfaceChanged(w, h);
} @Override
public void onSurfaceCreated(GL10 gl, EGLConfig config) {
super.onSurfaceCreated(gl, config);
SimpleNativeRenderer.demoSurfaceCreated();
} @Override
public void draw(GL10 gl) {
SimpleNativeRenderer.demoDrawFrame();
if (counter.frame()) Log.i("demo", counter.toString());
}
}
KudanAR - Android: 一个日本的可以作为comment的wiki,不错的样子。

The ARActivity class is an extension of the Activity class, used for displaying the camera feed and AR content. Make sure any activities in your project used to display AR content are extensions of ARActivity.

The ARRenderer is a singleton class used for rendering the camera image and AR content on screen.


接下来,让我欣赏下NDK的实现:

NDK

1. 主要是加载marker, model。( ** 与NFT应该有所不同,需进一步分析 ** )

JNIEXPORT void JNICALL JNIFUNCTION_DEMO(demoInitialise(JNIEnv* env, jobject object)) { 

    const char *model0file = "Data/models/Porsche_911_GT3.obj";       // 3D model
const char *model1file = "Data/models/Ferrari_Modena_Spider.obj";
  //////////////////////////////////////////////////////////////////////////////////////////////////////
models[].patternID = arwAddMarker("single;Data/hiro.patt;80");    // Marker
arwSetMarkerOptionBool(models[].patternID, ARW_MARKER_OPTION_SQUARE_USE_CONT_POSE_ESTIMATION, false);
arwSetMarkerOptionBool(models[].patternID, ARW_MARKER_OPTION_FILTERED, true); models[].obj = glmReadOBJ2(model0file, , ); // context 0, don't read textures yet.
if (!models[].obj) {
LOGE("Error loading model from file '%s'.", model0file);
exit(-);
} glmScale(models[].obj, 0.035f);
//glmRotate(models[0].obj, 3.14159f / 2.0f, 1.0f, 0.0f, 0.0f);
glmCreateArrays(models[].obj, GLM_SMOOTH | GLM_MATERIAL | GLM_TEXTURE);
models[].visible = false;
//////////////////////////////////////////////////////////////////////////////////////////////////////
models[].patternID = arwAddMarker("single;Data/kanji.patt;80");
arwSetMarkerOptionBool(models[].patternID, ARW_MARKER_OPTION_SQUARE_USE_CONT_POSE_ESTIMATION, false);
arwSetMarkerOptionBool(models[].patternID, ARW_MARKER_OPTION_FILTERED, true); models[].obj = glmReadOBJ2(model1file, , ); // context 0, don't read textures yet.
if (!models[].obj) {
LOGE("Error loading model from file '%s'.", model1file);
exit(-);
} glmScale(models[].obj, 0.035f);
//glmRotate(models[1].obj, 3.14159f / 2.0f, 1.0f, 0.0f, 0.0f);
glmCreateArrays(models[].obj, GLM_SMOOTH | GLM_MATERIAL | GLM_TEXTURE);
models[].visible = false;
}

2. 似乎也没做什么。

JNIEXPORT void JNICALL JNIFUNCTION_DEMO(demoSurfaceCreated(JNIEnv* env, jobject object)) {
glStateCacheFlush(); // Make sure we don't hold outdated OpenGL state.
for (int i = ; i < NUM_MODELS; i++) {
if (models[i].obj) {
glmDelete(models[i].obj, );  // init GLMmodel这个结构体 -->
models[i].obj = NULL;
}
}
}
typedef struct ARModel {
int patternID;
ARdouble transformationMatrix[];
bool visible;
GLMmodel* obj;
} ARModel;

3. 有了unity,是不是就可以忽略这些了呢?需求证。

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

    glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // Set the projection matrix to that provided by ARToolKit.
float proj[];
arwGetProjectionMatrix(proj);
glMatrixMode(GL_PROJECTION);
glLoadMatrixf(proj);
glMatrixMode(GL_MODELVIEW); glStateCacheEnableDepthTest();
glStateCacheEnableLighting();
glEnable(GL_LIGHT0); for (int i = ; i < NUM_MODELS; i++) {
models[i].visible = arwQueryMarkerTransformation(models[i].patternID, models[i].transformationMatrix); if (models[i].visible) {
glLoadMatrixf(models[i].transformationMatrix); glLightfv(GL_LIGHT0, GL_AMBIENT, lightAmbient);
glLightfv(GL_LIGHT0, GL_DIFFUSE, lightDiffuse);
glLightfv(GL_LIGHT0, GL_POSITION, lightPosition); glmDrawArrays(models[i].obj, );
}
}
}

看来,arBaseLib的分析是重点。

[Artoolkit] ARSimpleNativeCarsProj for Multi Markers Tracking的更多相关文章

  1. 本人AI知识体系导航 - AI menu

    Relevant Readable Links Name Interesting topic Comment Edwin Chen 非参贝叶斯   徐亦达老板 Dirichlet Process 学习 ...

  2. 【AR实验室】ARToolKit之Example篇

    0x00 - 前言 PS : 我突然意识到ARToolKit本质可能就是一个可以实时求解相机内外参的解决方案. 拿到一个新的SDK,90%的人应该都会先跑一下Example.拿到ARToolKit的S ...

  3. [Artoolkit] ARToolKit's SDK Structure on Android

    Most applications on Android are developed in Java, and Android provides a rich framework of classes ...

  4. [Artoolkit] Framework Analysis of nftSimple

    What is nftSimple? Loads NFT dataset names from a configuration file. The example uses the “Pinball. ...

  5. [Artoolkit] Marker of nftSimple

    重点看:markers.dat 的解析原理 1. int main(int argc, char** argv) { ]; const char *cparam_name = "Data2/ ...

  6. [译] AR SDK的种类比你想得要多!这里介绍七个棒棒哒

    作者:Eddie Offermann 原文:There are dozens more Augmented Reality SDKs than you think! Here are seven gr ...

  7. [Artoolkit] kpmMatching & Tracking of nftSimple

    1. kpmMatching thread main() --> loadNFTData() --> trackingInitInit() --> In static void *t ...

  8. 【AR实验室】ARToolKit之制作自己的Marker/NFT

    0x00 - 前言 看过example后,就会想自己动动手,这里改改那里修修.我们先试着添加自己喜欢的marker/nft进行识别. 比如我做了一个法拉利的marker: 还有网上找了一个法拉利log ...

  9. [Artoolkit] Marker Training

    Link: Documentation About the Traditional Template Square Marker Limitations (重要) Traditional Templa ...

随机推荐

  1. react-native组件封装与传值

    转载链接:http://www.ncloud.hk/%E6%8A%80%E6%9C%AF%E5%88%86%E4%BA%AB/react-native-component-packaging-and- ...

  2. 动态创建的 CEdit 被限制长度,增加 ES_AUTOHSCROLL 属性;被无法Tab激活焦点,增加 WS_TABSTOP 属性(转)

    动态创建的 CEdit 被限制长度,增加 ES_AUTOHSCROLL 属性:被无法Tab激活焦点,增加 WS_TABSTOP 属性. CEdit m_editUrl; // ES_AUTOHSCRO ...

  3. android:单位和尺寸

    为了要让程序拥有更好的屏幕适配能力,在指定控件和布局大小的时候 最好使用 match_parent 和 wrap_content,尽量避免将控件的宽和高设定一个固定值.不过在 有些情况下,仅仅使用 m ...

  4. [转载]震惊!QWidget竟然可以嵌入到QML中,QMl窗口句柄竟然是这样获取

      背景 记得在初学qml时,就被大佬告知Qml的实现有两种方式“view+item”和“engine+widow”,那么能不能将QWidget嵌入到QML中来呢,我收到的答案是不可以,原因是QML的 ...

  5. Spark2.3(三十四):Spark Structured Streaming之withWaterMark和windows窗口是否可以实现最近一小时统计

    WaterMark除了可以限定来迟数据范围,是否可以实现最近一小时统计? WaterMark目的用来限定参数计算数据的范围:比如当前计算数据内max timestamp是12::00,waterMar ...

  6. A very simple C++ module to encrypt/decrypt strings based on B64 and Vigenere ciper.

    A very simple C++ module to encrypt/decrypt strings based on B64 and Vigenere ciper. https://github. ...

  7. MDX Cookbook 11 - 计算 Year Over Year 增长 (同比计算) ParallelPeriod

    这一小节主要介绍如何在一个平行期间的度量值,当前值的对比对象是指当前值的上一年,上一个季度或者其它时间级别上与当前值同一时间点上的的那个对象.有一个非常常见的需求就是对比上一年同一个时间点的某个值来判 ...

  8. Docker linux安装

    Ubuntu下安装 sudo wget -qO- https://get.docker.com/  | shsudo usermod -aG docker imooc Centos7下安装 CentO ...

  9. 【转】java 读取 excel 2003 或 excel 2007

    package com.my.login; import java.io.File; import java.io.FileInputStream; import java.io.IOExceptio ...

  10. JS模块化:CommonJS和AMD(Require.js)

    早期的JS中,是没有模块化的概念的,这一情况直到09年的Node.js横空出世时有了好转,Node.js将JS作为服务端的编程语言,使得JS不得不寻求模块化的解决方案. 模块化概念 在JS中的模块是针 ...