54
LISTING PROGRAM
Kode Program splash_screen.xml:
<?xml version="1.0" encoding="utf-8"?> <RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="wrap_content"
android:layout_height="match_parent"
android:background="@color/holo_light_blue"
android:contentDescription="@string/content_desc_vuforia_backgroun d">
<TextView
android:id="@+id/splash_title" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentLeft="true" android:layout_alignParentTop="true" android:layout_marginTop="24dp" android:gravity="center"
android:text="@string/splash_title" android:textColor="@color/white"
android:textSize="@dimen/splash_title" android:textStyle="bold" />
<ImageView
android:id="@+id/logo_digipro" android:layout_width="200dp" android:layout_height="200dp"
android:layout_above="@+id/about_me" android:layout_centerHorizontal="true" android:layout_marginBottom="54dp"
android:contentDescription="@string/content_desc_vuforia_logo" android:scaleType="fitEnd"
android:src="@drawable/logo_digipro" />
<TextView
android:id="@+id/nim_ku"
android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentBottom="true" android:layout_centerHorizontal="true" android:layout_marginBottom="10dp" android:gravity="center"
android:text="@string/nim_ku" android:textColor="@color/white" android:textSize="@dimen/about_title" android:textStyle="bold" />
55
android:id="@+id/about_me"
android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_above="@+id/nim_ku" android:layout_centerHorizontal="true" android:layout_marginBottom="17dp" android:gravity="center"
android:text="@string/about_me" android:textColor="@color/white" android:textSize="@dimen/about_title" android:textStyle="bold" />
</RelativeLayout>
Kode Program about_screen.xml:
56
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent"
android:layout_height="match_parent" android:background="@color/black" android:orientation="vertical">
<TextView
android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginLeft="15dip" android:padding="10dip"
android:text="@string/about_title"
android:textColor="@color/holo_light_blue" android:textSize="@dimen/about_title" />
<View
android:layout_width="match_parent" android:layout_height="1dp"
android:layout_marginTop="10dp"
android:background="@color/holo_light_blue" />
<ScrollView
android:layout_width="match_parent" android:layout_height="match_parent"
android:layout_gravity="center_horizontal" android:layout_weight="1">
<TextView
android:id="@+id/about_text"
android:layout_width="match_parent" android:layout_height="wrap_content" android:padding="20dp"
android:textColor="@color/white"
android:textSize="@dimen/about_text" /> </ScrollView>
<Button
android:id="@+id/button_start" android:layout_width="fill_parent" android:layout_height="wrap_content"
android:gravity="center_horizontal|center_vertical" android:text="@string/button_start" />
</LinearLayout>
Kode Program camera_overlay.xml:
<?xml version="1.0" encoding="utf-8"?> <RelativeLayout
57
android:layout_width="match_parent" android:layout_height="match_parent">
<ProgressBar
android:id="@+id/loading_indicator" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_centerHorizontal="true" android:layout_centerVertical="true" />
58
Kode Program AboutScreen.java:
package com.qualcomm.QCARSamples.ImageTargets;
import android.app.Activity; import android.content.Intent; import android.os.Bundle; import android.text.Html;
import android.text.method.LinkMovementMethod; import android.view.View;
import android.view.View.OnClickListener; import android.widget.Button;
import android.widget.TextView;
public class AboutScreen extends Activity implements OnClickListener
{
private TextView mAboutText; private Button mStartButton;
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState); setContentView(R.layout.about_screen);
mAboutText = (TextView) findViewById(R.id.about_text);
mAboutText.setText(Html.fromHtml(getString(R.string.about_text)));
mAboutText.setMovementMethod(LinkMovementMethod.getInstance());
mAboutText.setLinkTextColor(getResources().getColor( R.color.holo_light_blue));
mStartButton = (Button) findViewById(R.id.button_start); mStartButton.setOnClickListener(this);
}
private void startARActivity() {
Intent i = new Intent(this, ImageTargets.class); startActivity(i);
}
public void onClick(View v) {
switch (v.getId()) {
59
} }}
Kode Program ImageTargets.java:
package com.qualcomm.QCARSamples.ImageTargets;
import java.lang.ref.WeakReference; import java.lang.reflect.Field; import java.util.Vector;
import android.app.Activity; import android.app.AlertDialog;
import android.content.DialogInterface; import android.content.pm.ActivityInfo; import android.content.res.Configuration; import android.graphics.Color;
import android.os.AsyncTask; import android.os.Bundle; import android.os.Handler; import android.os.Message;
import android.util.DisplayMetrics; import android.view.GestureDetector; import android.view.KeyEvent;
import android.view.LayoutInflater; import android.view.MenuItem;
import android.view.MotionEvent; import android.view.View;
import android.view.ViewGroup.LayoutParams; import android.view.WindowManager;
import android.widget.RelativeLayout; import android.widget.Toast;
import com.qualcomm.QCAR.QCAR;
public class ImageTargets extends Activity {
private static final int FOCUS_MODE_NORMAL = 0;
private static final int FOCUS_MODE_CONTINUOUS_AUTO = 1;
private static final int APPSTATUS_UNINITED = -1; private static final int APPSTATUS_INIT_APP = 0; private static final int APPSTATUS_INIT_QCAR = 1; private static final int APPSTATUS_INIT_TRACKER = 2; private static final int APPSTATUS_INIT_APP_AR = 3; private static final int APPSTATUS_LOAD_TRACKER = 4; private static final int APPSTATUS_INITED = 5; private static final int APPSTATUS_CAMERA_STOPPED = 6; private static final int APPSTATUS_CAMERA_RUNNING = 7;
private static final String NATIVE_LIB_SAMPLE = "ImageTargets";
60
static final int HIDE_LOADING_DIALOG = 0; static final int SHOW_LOADING_DIALOG = 1;
private View mLoadingDialogContainer;
private QCARSampleGLView mGlView;
private ImageTargetsRenderer mRenderer;
private int mScreenWidth = 0; private int mScreenHeight = 0;
private static final int INVALID_SCREEN_ROTATION = -1;
private int mLastScreenRotation = INVALID_SCREEN_ROTATION;
private int mAppStatus = APPSTATUS_UNINITED;
private InitQCARTask mInitQCARTask;
private LoadTrackerTask mLoadTrackerTask;
private Object mShutdownLock = new Object();
private int mQCARFlags = 0;
private Vector<Texture> mTextures;
private GestureDetector mGestureDetector;
private boolean mFlash = false;
private boolean mContAutofocus = false;
MenuItem mDataSetMenuItem = null;
boolean mIsMarkerDataSetActive = false;
private RelativeLayout mUILayout;
static {
loadLibrary(NATIVE_LIB_QCAR); loadLibrary(NATIVE_LIB_SAMPLE); }
static class LoadingDialogHandler extends Handler {
private final WeakReference<ImageTargets> mImageTargets;
LoadingDialogHandler(ImageTargets imageTargets) {
mImageTargets = new WeakReference<ImageTargets>( imageTargets);
61
public void handleMessage(Message msg) {
ImageTargets imageTargets = mImageTargets.get(); if (imageTargets == null)
{
return; }
if (msg.what == SHOW_LOADING_DIALOG) {
imageTargets.mLoadingDialogContainer .setVisibility(View.VISIBLE);
}
else if (msg.what == HIDE_LOADING_DIALOG) {
imageTargets.mLoadingDialogContainer.setVisibility(View.GONE); }
} }
private Handler loadingDialogHandler = new LoadingDialogHandler(this);
private class InitQCARTask extends AsyncTask<Void, Integer, Boolean>
{
private int mProgressValue = -1;
protected Boolean doInBackground(Void... params) {
synchronized (mShutdownLock) {
QCAR.setInitParameters(ImageTargets.this, mQCARFlags);
do {
mProgressValue = QCAR.init();
publishProgress(mProgressValue);
} while (!isCancelled() && mProgressValue >= 0 && mProgressValue < 100);
return (mProgressValue > 0); }
62
protected void onProgressUpdate(Integer... values) {
}
protected void onPostExecute(Boolean result) {
if (result) {
DebugLog.LOGD("InitQCARTask::onPostExecute: QCAR " +
"initialization successful");
updateApplicationStatus(APPSTATUS_INIT_TRACKER); }
else {
AlertDialog dialogError = new AlertDialog.Builder (
ImageTargets.this ).create();
dialogError.setButton (
DialogInterface.BUTTON_POSITIVE, "Close",
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which)
{
System.exit(1); }
} );
String logMessage;
if (mProgressValue == QCAR.INIT_DEVICE_NOT_SUPPORTED)
{
logMessage = "Failed to initialize QCAR because this " +
"device is not supported."; }
else {
logMessage = "Failed to initialize QCAR."; }
63
" Exiting.");
dialogError.setMessage(logMessage); dialogError.show();
} } }
private class LoadTrackerTask extends AsyncTask<Void, Integer, Boolean>
{
protected Boolean doInBackground(Void... params) {
synchronized (mShutdownLock) {
return (loadTrackerData() > 0); }
}
protected void onPostExecute(Boolean result) {
DebugLog.LOGD("LoadTrackerTask::onPostExecute: execution " +
(result ? "successful" : "failed"));
if (result) {
mIsMarkerDataSetActive = true;
updateApplicationStatus(APPSTATUS_INITED); }
else {
AlertDialog dialogError = new AlertDialog.Builder (
ImageTargets.this ).create();
dialogError.setButton (
DialogInterface.BUTTON_POSITIVE, "Close",
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which)
{
System.exit(1); }
64
dialogError.setMessage("Failed to load tracker data.");
dialogError.show(); }
} }
private void storeScreenDimensions() {
DisplayMetrics metrics = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(metrics); mScreenWidth = metrics.widthPixels;
mScreenHeight = metrics.heightPixels; }
protected void onCreate(Bundle savedInstanceState) {
DebugLog.LOGD("ImageTargets::onCreate"); super.onCreate(savedInstanceState);
mTextures = new Vector<Texture>(); loadTextures();
mQCARFlags = getInitializationFlags();
mGestureDetector = new GestureDetector(this, new GestureListener());
updateApplicationStatus(APPSTATUS_INIT_APP); }
private void loadTextures() {
mTextures.add(Texture.loadTextureFromApk("TextureBajuPertama 1.png",
getAssets()));
mTextures.add(Texture.loadTextureFromApk("TextureBajuKedua2. png",
getAssets())); }
private int getInitializationFlags() {
int flags = 0;
if (getOpenGlEsVersionNative() == 1) {
65
else {
flags = QCAR.GL_20; }
return flags; }
public native int getOpenGlEsVersionNative();
public native int initTracker(); public native void deinitTracker();
public native int loadTrackerData(); public native void destroyTrackerData();
public native void onQCARInitializedNative();
private native void startCamera(); private native void stopCamera();
private native void setProjectionMatrix();
protected void onResume() {
DebugLog.LOGD("ImageTargets::onResume"); super.onResume();
QCAR.onResume();
if (mAppStatus == APPSTATUS_CAMERA_STOPPED) {
updateApplicationStatus(APPSTATUS_CAMERA_RUNNING); }
if (mGlView != null) {
mGlView.setVisibility(View.VISIBLE); mGlView.onResume();
} }
private void updateActivityOrientation() {
Configuration config = getResources().getConfiguration();
boolean isPortrait = false;
switch (config.orientation) {
66
isPortrait = true; break;
case Configuration.ORIENTATION_LANDSCAPE: isPortrait = false;
break;
case Configuration.ORIENTATION_UNDEFINED: default:
break; }
DebugLog.LOGI("Activity is in "
+ (isPortrait ? "PORTRAIT" : "LANDSCAPE")); setActivityPortraitMode(isPortrait);
}
public void updateRenderView() {
int currentScreenRotation =
getWindowManager().getDefaultDisplay().getRotation(); if (currentScreenRotation != mLastScreenRotation) {
if (QCAR.isInitialized() && (mAppStatus == APPSTATUS_CAMERA_RUNNING))
{
DebugLog.LOGD("ImageTargets::updateRenderView");
storeScreenDimensions();
mRenderer.updateRendering(mScreenWidth, mScreenHeight);
setProjectionMatrix();
mLastScreenRotation = currentScreenRotation; }
} }
public void onConfigurationChanged(Configuration config) {
DebugLog.LOGD("ImageTargets::onConfigurationChanged"); super.onConfigurationChanged(config);
updateActivityOrientation();
storeScreenDimensions();
mLastScreenRotation = INVALID_SCREEN_ROTATION; }
67
{
DebugLog.LOGD("ImageTargets::onPause"); super.onPause();
if (mGlView != null) {
mGlView.setVisibility(View.INVISIBLE); mGlView.onPause();
}
if (mAppStatus == APPSTATUS_CAMERA_RUNNING) {
updateApplicationStatus(APPSTATUS_CAMERA_STOPPED); }
if (mFlash) {
mFlash = false;
activateFlash(mFlash); }
QCAR.onPause(); }
private native void deinitApplicationNative();
protected void onDestroy() {
DebugLog.LOGD("ImageTargets::onDestroy"); super.onDestroy();
if (mInitQCARTask != null && mInitQCARTask.getStatus() != InitQCARTask.Status.FINISHED)
{
mInitQCARTask.cancel(true); mInitQCARTask = null;
}
if (mLoadTrackerTask != null && mLoadTrackerTask.getStatus() != LoadTrackerTask.Status.FINISHED)
{
mLoadTrackerTask.cancel(true); mLoadTrackerTask = null;
}
synchronized (mShutdownLock) {
deinitApplicationNative();
68
mTextures = null;
destroyTrackerData();
deinitTracker();
QCAR.deinit(); }
System.gc(); }
private synchronized void updateApplicationStatus(int appStatus)
{
if (mAppStatus == appStatus) return;
mAppStatus = appStatus;
switch (mAppStatus) {
case APPSTATUS_INIT_APP: initApplication();
updateApplicationStatus(APPSTATUS_INIT_QCAR); break;
case APPSTATUS_INIT_QCAR: try
{
mInitQCARTask = new InitQCARTask(); mInitQCARTask.execute();
}
catch (Exception e) {
DebugLog.LOGE("Initializing QCAR SDK failed"); }
break;
case APPSTATUS_INIT_TRACKER: if (initTracker() > 0) {
updateApplicationStatus(APPSTATUS_INIT_APP_AR); }
break;
case APPSTATUS_INIT_APP_AR: initApplicationAR();
69
case APPSTATUS_LOAD_TRACKER: try
{
mLoadTrackerTask = new LoadTrackerTask(); mLoadTrackerTask.execute();
}
catch (Exception e) {
DebugLog.LOGE("Loading tracking data set failed");
} break;
case APPSTATUS_INITED:
onQCARInitializedNative();
mRenderer.mIsActive = true;
addContentView(mGlView, new LayoutParams(LayoutParams.MATCH_PARENT,
LayoutParams.MATCH_PARENT));
mUILayout.bringToFront();
updateApplicationStatus(APPSTATUS_CAMERA_RUNNING);
break;
case APPSTATUS_CAMERA_STOPPED: stopCamera();
break;
case APPSTATUS_CAMERA_RUNNING: startCamera();
loadingDialogHandler.sendEmptyMessage(HIDE_LOADING_DIALOG);
mUILayout.setBackgroundColor(Color.TRANSPARENT);
if (!setFocusMode(FOCUS_MODE_CONTINUOUS_AUTO)) {
mContAutofocus = false;
setFocusMode(FOCUS_MODE_NORMAL); }
else {
mContAutofocus = true; }
break;
70
throw new RuntimeException("Invalid application state");
} }
private native void setActivityPortraitMode(boolean isPortrait);
private void initApplication() {
int screenOrientation =
ActivityInfo.SCREEN_ORIENTATION_SENSOR;
if (screenOrientation ==
ActivityInfo.SCREEN_ORIENTATION_SENSOR) {
try {
Field fullSensorField = ActivityInfo.class
.getField("SCREEN_ORIENTATION_FULL_SENSOR");
screenOrientation = fullSensorField.getInt(null); }
catch (NoSuchFieldException e) {
}
catch (Exception e) {
e.printStackTrace(); }
}
setRequestedOrientation(screenOrientation);
updateActivityOrientation();
storeScreenDimensions();
getWindow().setFlags(
WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON, WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON); }
private native void initApplicationNative(int width, int height);
private void initApplicationAR() {
71
int depthSize = 16; int stencilSize = 0;
boolean translucent = QCAR.requiresAlpha();
mGlView = new QCARSampleGLView(this);
mGlView.init(mQCARFlags, translucent, depthSize, stencilSize);
mRenderer = new ImageTargetsRenderer(); mRenderer.mActivity = this;
mGlView.setRenderer(mRenderer);
LayoutInflater inflater = LayoutInflater.from(this); mUILayout = (RelativeLayout)
inflater.inflate(R.layout.camera_overlay, null, false);
mUILayout.setVisibility(View.VISIBLE); mUILayout.setBackgroundColor(Color.BLACK);
mLoadingDialogContainer =
mUILayout.findViewById(R.id.loading_indicator);
loadingDialogHandler.sendEmptyMessage(SHOW_LOADING_DIALOG);
addContentView(mUILayout, new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT)); }
private native void switchDatasetAsap();
private native boolean autofocus();
private native boolean setFocusMode(int mode);
private native boolean activateFlash(boolean flash);
public int getTextureCount() {
return mTextures.size(); }
public Texture getTexture(int i) {
return mTextures.elementAt(i); }
72
{
try {
System.loadLibrary(nLibName);
DebugLog.LOGI("Native library lib" + nLibName + ".so loaded");
return true; }
catch (UnsatisfiedLinkError ulee) {
DebugLog.LOGE("The library lib" + nLibName + ".so could not be loaded"); }
catch (SecurityException se) {
DebugLog.LOGE("The library lib" + nLibName +
".so was not allowed to be loaded"); }
return false; }
public boolean onKeyUp(int keyCode, KeyEvent event) {
if (keyCode == KeyEvent.KEYCODE_MENU) {
showCameraOptionsDialog(); return true;
}
return super.onKeyUp(keyCode, event); }
public boolean onTouchEvent(MotionEvent event) {
return mGestureDetector.onTouchEvent(event); }
private class GestureListener extends
GestureDetector.SimpleOnGestureListener {
public boolean onDown(MotionEvent e) {
return true; }
public boolean onSingleTapUp(MotionEvent e) {
73
mContAutofocus = false;
return true; }
public boolean onDoubleTap(MotionEvent e) {
showCameraOptionsDialog(); return true;
} }
private void showCameraOptionsDialog() {
if (mAppStatus < APPSTATUS_INITED) {
return; }
final int itemCameraIndex = 0; final int itemAutofocusIndex = 1; final int itemSwitchDatasetIndex = 2;
AlertDialog cameraOptionsDialog = null;
CharSequence[] items =
{ getString(R.string.menu_flash_on),
getString(R.string.menu_contAutofocus_off), };
if (mFlash) {
items[itemCameraIndex] = (getString(R.string.menu_flash_off)); }
else {
items[itemCameraIndex] = (getString(R.string.menu_flash_on)); }
if (mContAutofocus) {
items[itemAutofocusIndex] =
(getString(R.string.menu_contAutofocus_off)); }
else {
74
AlertDialog.Builder cameraOptionsDialogBuilder = new AlertDialog.Builder(
ImageTargets.this); cameraOptionsDialogBuilder
.setTitle(getString(R.string.menu_camera_title)); cameraOptionsDialogBuilder.setItems(items,
75
if
(setFocusMode(FOCUS_MODE_CONTINUOUS_AUTO)) {
mContAutofocus = true; }
else {
Toast.makeText (
ImageTargets.this, "Unable to activate Continuous Auto-Focus",
Toast.LENGTH_SHORT ).show();
} }
dialog.dismiss(); }
else if (item == itemSwitchDatasetIndex) {
switchDatasetAsap(); mIsMarkerDataSetActive = !mIsMarkerDataSetActive;
dialog.dismiss(); }
} });
cameraOptionsDialog = cameraOptionsDialogBuilder.create(); cameraOptionsDialog.show();
76
Kode Program ImageTargets.cpp:
#include<jni.h>
#include<android/log.h>
#include<stdio.h>
#include<string.h>
#include<assert.h>
#ifdef USE_OPENGL_ES_1_1
#include<GLES/gl.h>
#include<GLES/glext.h>
#else
#include<GLES2/gl2.h>
#include<GLES2/gl2ext.h>
#endif
#include<QCAR/QCAR.h>
#include<QCAR/CameraDevice.h> #include<QCAR/Renderer.h>
#include<QCAR/VideoBackgroundConfig.h>
#include<QCAR/Trackable.h>
#include<QCAR/TrackableResult.h>
#include<QCAR/Tool.h> #include<QCAR/Tracker.h>
#include<QCAR/TrackerManager.h> #include<QCAR/ImageTracker.h>
#include<QCAR/CameraCalibration.h>
#include<QCAR/UpdateCallback.h> #include<QCAR/DataSet.h>
#include"SampleUtils.h"
#include"Texture.h" #include"CubeShaders.h" #include"bajuPertama.h" #include"bajuKedua.h" #include<sys/time.h> int lastTrackableId = -1; float animationTime = 0;
#define TOTAL_ANIMATION_DURATION 5.0f //seconds #ifdef __cplusplus
extern"C"
{
#endif
int textureCount = 0;
Texture** textures = 0;
77
unsignedint shaderProgramID = 0;
GLint vertexHandle = 0; GLint textureCoordHandle = 0; GLint mvpMatrixHandle = 0; GLint texSampler2DHandle = 0;
#endif
unsignedint screenWidth = 0;
unsignedint screenHeight = 0;
bool isActivityInPortraitMode = false;
QCAR::Matrix44F projectionMatrix;
staticconstfloat kObjectScale = 1500.0f;
QCAR::DataSet* dataSetMarker = 0;
bool switchDataSetAsap = false;
classImageTargets_UpdateCallback : public QCAR::UpdateCallback {
virtualvoidQCAR_onUpdate(QCAR::State&/*state*/) {
if (switchDataSetAsap) {
switchDataSetAsap = false;
QCAR::TrackerManager& trackerManager = QCAR::TrackerManager::getInstance();
QCAR::ImageTracker* imageTracker =
static_cast<QCAR::ImageTracker*>(
trackerManager.getTracker(QCAR::Tracker::IMAGE_TRACKER));
if (imageTracker == 0 || dataSetMarker == 0 ||
imageTracker->getActiveDataSet() == 0) {
LOG("Failed to switch data set.");
return;
} } } };
ImageTargets_UpdateCallback updateCallback;
JNIEXPORT int JNICALL
Java_com_qualcomm_QCARSamples_ImageTargets_ImageTargets_getOpenGlE sVersionNative(JNIEnv *, jobject)
{
#ifdef USE_OPENGL_ES_1_1
return 1;
78
return 2; #endif
}
JNIEXPORT void JNICALL
Java_com_qualcomm_QCARSamples_ImageTargets_ImageTargets_setActivit yPortraitMode(JNIEnv *, jobject, jboolean isPortrait)
{
isActivityInPortraitMode = isPortrait; }
JNIEXPORT void JNICALL
Java_com_qualcomm_QCARSamples_ImageTargets_ImageTargets_switchData setAsap(JNIEnv *, jobject)
{
switchDataSetAsap = true; }
JNIEXPORT int JNICALL
Java_com_qualcomm_QCARSamples_ImageTargets_ImageTargets_initTracke r(JNIEnv *, jobject)
{
LOG("Java_com_qualcomm_QCARSamples_ImageTargets_ImageTargets_initT racker");
QCAR::TrackerManager& trackerManager = QCAR::TrackerManager::getInstance();
QCAR::Tracker* tracker =
trackerManager.initTracker(QCAR::Tracker::IMAGE_TRACKER);
if (tracker == NULL) {
LOG("Failed to initialize ImageTracker.");
return 0; }
LOG("Successfully initialized ImageTracker.");
return 1; }
JNIEXPORT void JNICALL
Java_com_qualcomm_QCARSamples_ImageTargets_ImageTargets_deinitTrac ker(JNIEnv *, jobject)
{
79
QCAR::TrackerManager& trackerManager = QCAR::TrackerManager::getInstance();
trackerManager.deinitTracker(QCAR::Tracker::IMAGE_TRACKER); }
JNIEXPORT int JNICALL
Java_com_qualcomm_QCARSamples_ImageTargets_ImageTargets_loadTracke rData(JNIEnv *, jobject)
{
LOG("Java_com_qualcomm_QCARSamples_ImageTargets_ImageTargets_loadT rackerData");
QCAR::TrackerManager& trackerManager = QCAR::TrackerManager::getInstance();
QCAR::ImageTracker* imageTracker =
static_cast<QCAR::ImageTracker*>(
trackerManager.getTracker(QCAR::Tracker::IMAGE_TRACKER));
if (imageTracker == NULL) {
LOG("Failed to load tracking data set because the ImageTracker has not"
" been initialized.");
return 0; }
dataSetMarker = imageTracker->createDataSet();
if (dataSetMarker == 0) {
LOG("Failed to create a new tracking data.");
return 0; }
if (!dataSetMarker->load("Marker.xml", QCAR::DataSet::STORAGE_APPRESOURCE)) {
LOG("Failed to load data set.");
return 0; }
if (!imageTracker->activateDataSet(dataSetMarker)) {
LOG("Failed to activate data set.");
return 0; }
LOG("Successfully loaded and activated data set.");
return 1; }
80
Java_com_qualcomm_QCARSamples_ImageTargets_ImageTargets_destroyTra ckerData(JNIEnv *, jobject)
{
LOG("Java_com_qualcomm_QCARSamples_ImageTargets_ImageTargets_destr oyTrackerData");
QCAR::TrackerManager& trackerManager = QCAR::TrackerManager::getInstance();
QCAR::ImageTracker* imageTracker =
static_cast<QCAR::ImageTracker*>(
trackerManager.getTracker(QCAR::Tracker::IMAGE_TRACKER));
if (imageTracker == NULL) {
LOG("Failed to destroy the tracking data set because the ImageTracker has not"
" been initialized.");
return 0; }
if (dataSetMarker != 0) {
if (imageTracker->getActiveDataSet() == dataSetMarker && !imageTracker->deactivateDataSet(dataSetMarker)) {
LOG("Failed to destroy the tracking data set StonesAndChips because the data set "
"could not be deactivated.");
return 0; }
if (!imageTracker->destroyDataSet(dataSetMarker)) {
LOG("Failed to destroy the tracking data set Marker.");
return 0; }
LOG("Successfully destroyed the data set Marker."); dataSetMarker = 0;
}
return 1; }
JNIEXPORT void JNICALL
Java_com_qualcomm_QCARSamples_ImageTargets_ImageTargets_onQCARInit ializedNative(JNIEnv *, jobject)
{
QCAR::setHint(QCAR::HINT_MAX_SIMULTANEOUS_IMAGE_TARGETS, 2);
81
unsignedlonggetCurrentTimeMilliseconds()
{
structtimeval tv;
gettimeofday(&tv, NULL);
unsignedlong s = tv.tv_sec * 1000;
unsignedlong us = tv.tv_usec / 1000;
return s + us;
}
JNIEXPORT void JNICALL
Java_com_qualcomm_QCARSamples_ImageTargets_ImageTargetsRenderer_re nderFrame(JNIEnv *, jobject)
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
QCAR::State state = QCAR::Renderer::getInstance().begin();
QCAR::Renderer::getInstance().drawVideoBackground();
#ifdef USE_OPENGL_ES_1_1
glEnableClientState(GL_VERTEX_ARRAY);
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
glEnable(GL_TEXTURE_2D); glDisable(GL_LIGHTING);
#endif
glEnable(GL_DEPTH_TEST);
glEnable(GL_CULL_FACE); glCullFace(GL_BACK);
if(QCAR::Renderer::getInstance().getVideoBackgroundConfig().mRefle ction == QCAR::VIDEO_BACKGROUND_REFLECTION_ON)
glFrontFace(GL_CW);
else
glFrontFace(GL_CCW);
staticfloat lastTime = 0.001f * getCurrentTimeMilliseconds();
if (state.getNumTrackableResults() == 0) {
lastTime = 0.001f * getCurrentTimeMilliseconds(); animationTime = 0;
lastTrackableId = -1; }
for(int tIdx = 0; tIdx < state.getNumTrackableResults(); tIdx++) {
const QCAR::TrackableResult* result = state.getTrackableResult(tIdx);
const QCAR::Trackable& trackable = result->getTrackable();
if (trackable.getId() != lastTrackableId) {
82
lastTrackableId = trackable.getId(); }
float currentTime = 0.001f * getCurrentTimeMilliseconds();
float elapsedTime = currentTime - lastTime;
animationTime += elapsedTime;
lastTime = currentTime;
if (animationTime > TOTAL_ANIMATION_DURATION) {
animationTime = 0; }
QCAR::Matrix44F modelViewMatrix =
QCAR::Tool::convertPose2GLMatrix(result->getPose());
int textureIndex;
if (strcmp(trackable.getName(), "MarkerSatu") == 0) {
textureIndex = 0;
glVertexAttribPointer(vertexHandle,3, GL_FLOAT, GL_FALSE, 0, bajuPertamaVerts);
glVertexAttribPointer(textureCoordHandle, 2, GL_FLOAT, GL_FALSE, 0, bajuPertamaTexCoords);
}
elseif (strcmp(trackable.getName(), "MarkerDua") == 0) {
textureIndex = 1;
glVertexAttribPointer(vertexHandle,3, GL_FLOAT, GL_FALSE, 0, bajuKeduaVerts);
glVertexAttribPointer(textureCoordHandle, 2, GL_FLOAT, GL_FALSE, 0, bajuKeduaTexCoords);
}
const Texture* const thisTexture = textures[textureIndex];
#ifdef USE_OPENGL_ES_1_1
glMatrixMode(GL_PROJECTION);
glLoadMatrixf(projectionMatrix.data);
glMatrixMode(GL_MODELVIEW);
glLoadMatrixf(modelViewMatrix.data); glTranslatef(0.f, 0.f, kObjectScale);
glScalef(kObjectScale, kObjectScale, kObjectScale);
glBindTexture(GL_TEXTURE_2D, thisTexture->mTextureID);
if (textureIndex==0)
glDrawArrays(GL_TRIANGLES, 0, bajuPertamaNumVerts);
elseif (textureIndex==1)
83
#else
QCAR::Matrix44F modelViewProjection;
float angle = 90.0f;
float totalRotationAngle = 90.0f;
float currentRotationAngle = 360.0f * (animationTime /
TOTAL_ANIMATION_DURATION);
SampleUtils::rotatePoseMatrix(currentRotationAngle, 0.f, 0.f, 1.f,
&modelViewMatrix.data[0]);
SampleUtils::translatePoseMatrix(0.0f, 0.0f, 100, &modelViewMatrix.data[0]);
SampleUtils::rotatePoseMatrix(angle, 1.0f, 0.0f, 0.0f, &modelViewMatrix.data[0]);
SampleUtils::scalePoseMatrix(kObjectScale, kObjectScale, kObjectScale,
&modelViewMatrix.data[0]);
SampleUtils::multiplyMatrix(&projectionMatrix.data[0], &modelViewMatrix.data[0] ,
&modelViewProjection.data[0]);
glUseProgram(shaderProgramID);
glEnableVertexAttribArray(vertexHandle);
glEnableVertexAttribArray(textureCoordHandle);
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, thisTexture->mTextureID); glUniform1i(texSampler2DHandle, 0 /*GL_TEXTURE0*/); glUniformMatrix4fv(mvpMatrixHandle, 1, GL_FALSE,
(GLfloat*)&modelViewProjection.data[0] );
if (textureIndex==0)
glDrawArrays(GL_TRIANGLES, 0, bajuPertamaNumVerts);
elseif (textureIndex==1)
glDrawArrays(GL_TRIANGLES, 0, bajuKeduaNumVerts);
SampleUtils::checkGlError("ImageTargets renderFrame");
#endif
}
glDisable(GL_DEPTH_TEST);
#ifdef USE_OPENGL_ES_1_1 glDisable(GL_TEXTURE_2D);
glDisableClientState(GL_VERTEX_ARRAY);
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
#else
glDisableVertexAttribArray(vertexHandle);
84
#endif
QCAR::Renderer::getInstance().end(); }
void
configureVideoBackground()
{
QCAR::CameraDevice& cameraDevice = QCAR::CameraDevice::getInstance();
QCAR::VideoMode videoMode = cameraDevice.
getVideoMode(QCAR::CameraDevice::MODE_DEFAULT);
QCAR::VideoBackgroundConfig config; config.mEnabled = true;
config.mSynchronous = true; config.mPosition.data[0] = 0.0f; config.mPosition.data[1] = 0.0f;
if (isActivityInPortraitMode) {
config.mSize.data[0] = videoMode.mHeight * (screenHeight / (float)videoMode.mWidth);
config.mSize.data[1] = screenHeight;
if(config.mSize.data[0] < screenWidth) {
LOG("Correcting rendering background size to handle missmatch between screen and video aspect ratios.");
config.mSize.data[0] = screenWidth; config.mSize.data[1] = screenWidth * (videoMode.mWidth / (float)videoMode.mHeight);
} }
else
{
config.mSize.data[0] = screenWidth; config.mSize.data[1] = videoMode.mHeight * (screenWidth / (float)videoMode.mWidth);
if(config.mSize.data[1] < screenHeight) {
LOG("Correcting rendering background size to handle missmatch between screen and video aspect ratios.");
config.mSize.data[0] = screenHeight
* (videoMode.mWidth / (float)videoMode.mHeight);
85
} }
LOG("Configure Video Background : Video (%d,%d), Screen (%d,%d), mSize (%d,%d)", videoMode.mWidth, videoMode.mHeight, screenWidth, screenHeight, config.mSize.data[0],
config.mSize.data[1]);
QCAR::Renderer::getInstance().setVideoBackgroundConfig(config); }
JNIEXPORT void JNICALL
Java_com_qualcomm_QCARSamples_ImageTargets_ImageTargets_initApplic ationNative(
JNIEnv* env, jobject obj, jint width, jint height)
{
LOG("Java_com_qualcomm_QCARSamples_ImageTargets_ImageTargets_initA pplicationNative");
screenWidth = width; screenHeight = height;
jclass activityClass = env->GetObjectClass(obj);
jmethodID getTextureCountMethodID = env->GetMethodID(activityClass,
"getTextureCount", "()I");
if (getTextureCountMethodID == 0) {
LOG("Function getTextureCount() not found.");
return; }
textureCount = env->CallIntMethod(obj, getTextureCountMethodID);
if (!textureCount) {
LOG("getTextureCount() returned zero.");
return; }
textures = new Texture*[textureCount];
jmethodID getTextureMethodID = env->GetMethodID(activityClass, "getTexture",
"(I)Lcom/qualcomm/QCARSamples/ImageTargets/Texture;");
if (getTextureMethodID == 0) {
86
return;
}
for (int i = 0; i < textureCount; ++i)
{
jobject textureObject = env->CallObjectMethod(obj, getTextureMethodID, i);
if (textureObject == NULL)
{
LOG("GetTexture() returned zero pointer");
return; }
textures[i] = Texture::create(env, textureObject); }
LOG("Java_com_qualcomm_QCARSamples_ImageTargets_ImageTargets_initA pplicationNative finished");
}
JNIEXPORT void JNICALL
Java_com_qualcomm_QCARSamples_ImageTargets_ImageTargets_deinitAppl icationNative(
JNIEnv* env, jobject obj)
{
LOG("Java_com_qualcomm_QCARSamples_ImageTargets_ImageTargets_deini tApplicationNative");
if (textures != 0) {
for (int i = 0; i < textureCount; ++i) {
delete textures[i];
textures[i] = NULL; }
delete[]textures;
textures = NULL;
textureCount = 0; }
}
JNIEXPORT void JNICALL
Java_com_qualcomm_QCARSamples_ImageTargets_ImageTargets_startCamer a(JNIEnv *,
87
LOG("Java_com_qualcomm_QCARSamples_ImageTargets_ImageTargets_start Camera");
QCAR::CameraDevice::CAMERA camera = QCAR::CameraDevice::CAMERA_DEFAULT;
if (!QCAR::CameraDevice::getInstance().init(camera)) return;
configureVideoBackground();
if (!QCAR::CameraDevice::getInstance().selectVideoMode(
QCAR::CameraDevice::MODE_DEFAULT))
return;
if (!QCAR::CameraDevice::getInstance().start())
return;
QCAR::TrackerManager& trackerManager = QCAR::TrackerManager::getInstance();
QCAR::Tracker* imageTracker =
trackerManager.getTracker(QCAR::Tracker::IMAGE_TRACKER);
if(imageTracker != 0)
imageTracker->start(); }
JNIEXPORT void JNICALL
Java_com_qualcomm_QCARSamples_ImageTargets_ImageTargets_stopCamera (JNIEnv *, jobject)
{
LOG("Java_com_qualcomm_QCARSamples_ImageTargets_ImageTargets_stopC amera");
QCAR::TrackerManager& trackerManager = QCAR::TrackerManager::getInstance();
QCAR::Tracker* imageTracker =
trackerManager.getTracker(QCAR::Tracker::IMAGE_TRACKER);
if(imageTracker != 0)
imageTracker->stop();
QCAR::CameraDevice::getInstance().stop(); QCAR::CameraDevice::getInstance().deinit(); }
JNIEXPORT void JNICALL
Java_com_qualcomm_QCARSamples_ImageTargets_ImageTargets_setProject ionMatrix(JNIEnv *, jobject)
{
88
const QCAR::CameraCalibration& cameraCalibration =
QCAR::CameraDevice::getInstance().getCameraCalibration(); projectionMatrix =
QCAR::Tool::getProjectionGL(cameraCalibration, 2.0f, 2500.0f); }
JNIEXPORT jboolean JNICALL
Java_com_qualcomm_QCARSamples_ImageTargets_ImageTargets_activateFl ash(JNIEnv*, jobject, jboolean flash)
{
return
QCAR::CameraDevice::getInstance().setFlashTorchMode((flash==JNI_TR UE)) ? JNI_TRUE : JNI_FALSE;
}
JNIEXPORT jboolean JNICALL
Java_com_qualcomm_QCARSamples_ImageTargets_ImageTargets_autofocus( JNIEnv*, jobject)
{
return
QCAR::CameraDevice::getInstance().setFocusMode(QCAR::CameraDevice: :FOCUS_MODE_TRIGGERAUTO) ? JNI_TRUE : JNI_FALSE;
}
JNIEXPORT jboolean JNICALL
Java_com_qualcomm_QCARSamples_ImageTargets_ImageTargets_setFocusMo de(JNIEnv*, jobject, jint mode)
{
int qcarFocusMode;
switch ((int)mode) {
case 0:
qcarFocusMode = QCAR::CameraDevice::FOCUS_MODE_NORMAL;
break;
case 1:
qcarFocusMode =
QCAR::CameraDevice::FOCUS_MODE_CONTINUOUSAUTO;
break;
case 2:
qcarFocusMode =
QCAR::CameraDevice::FOCUS_MODE_INFINITY;
break;
case 3:
qcarFocusMode = QCAR::CameraDevice::FOCUS_MODE_MACRO;
break;
89
return JNI_FALSE;
}
return
QCAR::CameraDevice::getInstance().setFocusMode(qcarFocusMode) ? JNI_TRUE : JNI_FALSE;
}
JNIEXPORT void JNICALL
Java_com_qualcomm_QCARSamples_ImageTargets_ImageTargetsRenderer_in itRendering(
JNIEnv* env, jobject obj)
{
LOG("Java_com_qualcomm_QCARSamples_ImageTargets_ImageTargetsRender er_initRendering");
glClearColor(0.0f, 0.0f, 0.0f, QCAR::requiresAlpha() ? 0.0f : 1.0f);
for (int i = 0; i < textureCount; ++i) {
glGenTextures(1, &(textures[i]->mTextureID));
glBindTexture(GL_TEXTURE_2D, textures[i]->mTextureID); glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, textures[i]->mWidth,
textures[i]->mHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE,
(GLvoid*) textures[i]->mData); }
#ifndef USE_OPENGL_ES_1_1
shaderProgramID =
SampleUtils::createProgramFromBuffer(cubeMeshVertexShader, cubeFragmentShader);
vertexHandle = glGetAttribLocation(shaderProgramID, "vertexPosition");
textureCoordHandle = glGetAttribLocation(shaderProgramID, "vertexTexCoord");
mvpMatrixHandle = glGetUniformLocation(shaderProgramID, "modelViewProjectionMatrix");
texSampler2DHandle = glGetUniformLocation(shaderProgramID, "texSampler2D");
90
}
JNIEXPORT void JNICALL
Java_com_qualcomm_QCARSamples_ImageTargets_ImageTargetsRenderer_up dateRendering(
JNIEnv* env, jobject obj, jint width, jint height)
{
LOG("Java_com_qualcomm_QCARSamples_ImageTargets_ImageTargetsRender er_updateRendering");
screenWidth = width; screenHeight = height;
configureVideoBackground(); }
#ifdef __cplusplus }