compile fix for gles3 on android, copied example folder to create gles3 android example

This commit is contained in:
Thomas Hogarth 2018-05-23 02:01:21 +01:00
parent 1b56fc1c00
commit b67a7c5981
24 changed files with 1872 additions and 0 deletions

View File

@ -0,0 +1,22 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="osg.AndroidExample"
android:installLocation="preferExternal"
android:versionCode="1"
android:versionName="1.0">
<uses-sdk android:targetSdkVersion="24" android:minSdkVersion="18"></uses-sdk>
<uses-feature android:glEsVersion="0x00030000"/> <!-- OpenGL min requirements (2.0) -->
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
<application android:label="@string/app_name" android:icon="@drawable/osg">
<activity android:name=".osgViewer"
android:label="@string/app_name" android:screenOrientation="landscape"> <!-- Force screen to landscape -->
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>

View File

@ -0,0 +1,11 @@
# This file is automatically generated by Android Tools.
# Do not modify this file -- YOUR CHANGES WILL BE ERASED!
#
# This file must be checked in Version Control Systems.
#
# To customize properties used by the Ant build system use,
# "build.properties", and override values to adapt the script to your
# project structure.
# Project target.
target=android-8

View File

@ -0,0 +1,67 @@
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := osgNativeLib
### Main Install dir
OSG_ANDROID_DIR := < type your install directory >
LIBDIR := $(OSG_ANDROID_DIR)/obj/local/armeabi
ifeq ($(TARGET_ARCH_ABI),armeabi-v7a)
LOCAL_ARM_NEON := true
LIBDIR := $(OSG_ANDROID_DIR)/obj/local/armeabi-v7a
endif
### Add all source file names to be included in lib separated by a whitespace
LOCAL_C_INCLUDES:= $(OSG_ANDROID_DIR)/include
LOCAL_CFLAGS := -Werror -fno-short-enums
LOCAL_CPPFLAGS := -DOSG_LIBRARY_STATIC
LOCAL_LDLIBS := -llog -lGLESv3 -lz
LOCAL_SRC_FILES := osgNativeLib.cpp OsgMainApp.cpp OsgAndroidNotifyHandler.cpp
LOCAL_LDFLAGS := -L $(LIBDIR) \
-losgdb_dds \
-losgdb_openflight \
-losgdb_tga \
-losgdb_rgb \
-losgdb_osgterrain \
-losgdb_osg \
-losgdb_ive \
-losgdb_deprecated_osgviewer \
-losgdb_deprecated_osgvolume \
-losgdb_deprecated_osgtext \
-losgdb_deprecated_osgterrain \
-losgdb_deprecated_osgsim \
-losgdb_deprecated_osgshadow \
-losgdb_deprecated_osgparticle \
-losgdb_deprecated_osgfx \
-losgdb_deprecated_osganimation \
-losgdb_deprecated_osg \
-losgdb_serializers_osgvolume \
-losgdb_serializers_osgtext \
-losgdb_serializers_osgterrain \
-losgdb_serializers_osgsim \
-losgdb_serializers_osgshadow \
-losgdb_serializers_osgparticle \
-losgdb_serializers_osgmanipulator \
-losgdb_serializers_osgfx \
-losgdb_serializers_osganimation \
-losgdb_serializers_osg \
-losgViewer \
-losgVolume \
-losgTerrain \
-losgText \
-losgShadow \
-losgSim \
-losgParticle \
-losgManipulator \
-losgGA \
-losgFX \
-losgDB \
-losgAnimation \
-losgUtil \
-losg \
-lOpenThreads
include $(BUILD_SHARED_LIBRARY)

View File

@ -0,0 +1,11 @@
#ANDROID APPLICATION MAKEFILE
APP_BUILD_SCRIPT := $(call my-dir)/Android.mk
#APP_PROJECT_PATH := $(call my-dir)
APP_OPTIM := release
APP_PLATFORM := android-18
APP_STL := gnustl_static
APP_CPPFLAGS := -fexceptions -frtti
APP_ABI := armeabi-v7a
APP_MODULES := osgNativeLib

View File

@ -0,0 +1,38 @@
/*
* OsgAndroidNotifyHandler.cpp
*
* Created on: 31/05/2011
* Author: Jorge Izquierdo Ciges
*/
#include "OsgAndroidNotifyHandler.hpp"
#include <iostream>
void OsgAndroidNotifyHandler::setTag(std::string tag){
_tag = tag;
}
void OsgAndroidNotifyHandler::notify(osg::NotifySeverity severity, const char *message){
switch ( severity ) {
case osg::DEBUG_FP:
__android_log_write(ANDROID_LOG_VERBOSE,_tag.c_str(),message);
break;
case osg::DEBUG_INFO:
__android_log_write(ANDROID_LOG_DEBUG,_tag.c_str(),message);
break;
case osg::NOTICE:
case osg::INFO:
__android_log_write(ANDROID_LOG_INFO,_tag.c_str(),message);
break;
case osg::WARN:
__android_log_write(ANDROID_LOG_WARN,_tag.c_str(),message);
break;
case osg::FATAL:
case osg::ALWAYS:
__android_log_write(ANDROID_LOG_ERROR,_tag.c_str(),message);
break;
default:
__android_log_write(ANDROID_LOG_DEBUG,_tag.c_str(),message);
break;
}
}

View File

@ -0,0 +1,26 @@
/*
* OsgAndroidNotifyHandler.hpp
*
* Created on: 31/05/2011
* Author: Jorge Izquierdo Ciges
*/
#ifndef OSGANDROIDNOTIFYHANDLER_HPP_
#define OSGANDROIDNOTIFYHANDLER_HPP_
#include <android/log.h>
#include <osg/Notify>
#include <string>
class OSG_EXPORT OsgAndroidNotifyHandler : public osg::NotifyHandler
{
private:
std::string _tag;
public:
void setTag(std::string tag);
void notify(osg::NotifySeverity severity, const char *message);
};
#endif /* OSGANDROIDNOTIFYHANDLER_HPP_ */

View File

@ -0,0 +1,217 @@
#include "OsgMainApp.hpp"
OsgMainApp::OsgMainApp(){
_lodScale = 1.0f;
_prevFrame = 0;
_initialized = false;
_clean_scene = false;
}
OsgMainApp::~OsgMainApp(){
}
void OsgMainApp::loadModels(){
if(_vModelsToLoad.size()==0) return;
osg::notify(osg::ALWAYS)<<"There are "<<_vModelsToLoad.size()<<" models to load"<<std::endl;
Model newModel;
for(unsigned int i=0; i<_vModelsToLoad.size(); i++){
newModel = _vModelsToLoad[i];
osg::notify(osg::ALWAYS)<<"Loading: "<<newModel.filename<<std::endl;
osg::ref_ptr<osg::Node> loadedModel = osgDB::readRefNodeFile(newModel.filename);
if (loadedModel == 0) {
osg::notify(osg::ALWAYS)<<"Model not loaded"<<std::endl;
} else {
osg::notify(osg::ALWAYS)<<"Model loaded"<<std::endl;
_vModels.push_back(newModel);
loadedModel->setName(newModel.name);
osg::Shader * vshader = new osg::Shader(osg::Shader::VERTEX, gVertexShader );
osg::Shader * fshader = new osg::Shader(osg::Shader::FRAGMENT, gFragmentShader );
osg::Program * prog = new osg::Program;
prog->addShader ( vshader );
prog->addShader ( fshader );
loadedModel->getOrCreateStateSet()->setAttribute ( prog );
_root->addChild(loadedModel);
}
}
osgViewer::Viewer::Windows windows;
_viewer->getWindows(windows);
for(osgViewer::Viewer::Windows::iterator itr = windows.begin();itr != windows.end();++itr)
{
(*itr)->getState()->setUseModelViewAndProjectionUniforms(true);
(*itr)->getState()->setUseVertexAttributeAliasing(true);
}
_viewer->setSceneData(NULL);
_viewer->setSceneData(_root.get());
_manipulator->getNode();
_viewer->home();
_viewer->getDatabasePager()->clear();
_viewer->getDatabasePager()->registerPagedLODs(_root.get());
_viewer->getDatabasePager()->setUpThreads(3, 1);
_viewer->getDatabasePager()->setTargetMaximumNumberOfPageLOD(2);
_viewer->getDatabasePager()->setUnrefImageDataAfterApplyPolicy(true, true);
_vModelsToLoad.clear();
}
void OsgMainApp::deleteModels(){
if(_vModelsToDelete.size()==0) return;
osg::notify(osg::ALWAYS)<<"There are "<<_vModelsToDelete.size()<<" models to delete"<<std::endl;
Model modelToDelete;
for(unsigned int i=0; i<_vModelsToDelete.size(); i++){
modelToDelete = _vModelsToDelete[i];
osg::notify(osg::ALWAYS)<<"Deleting: "<<modelToDelete.name<<std::endl;
for(unsigned int j=_root->getNumChildren(); j>0; j--){
osg::ref_ptr<osg::Node> children = _root->getChild(j-1);
if(children->getName() == modelToDelete.name){
_root->removeChild(children);
}
}
}
_vModelsToDelete.clear();
osg::notify(osg::ALWAYS)<<"finished"<<std::endl;
}
//Initialization function
void OsgMainApp::initOsgWindow(int x,int y,int width,int height){
__android_log_write(ANDROID_LOG_ERROR, "OSGANDROID",
"Initializing geometry");
//Pending
_notifyHandler = new OsgAndroidNotifyHandler();
_notifyHandler->setTag("Osg Viewer");
osg::setNotifyHandler(_notifyHandler);
osg::notify(osg::ALWAYS)<<"Testing"<<std::endl;
_viewer = new osgViewer::Viewer();
_viewer->setUpViewerAsEmbeddedInWindow(x, y, width, height);
_viewer->setThreadingModel(osgViewer::ViewerBase::SingleThreaded);
_root = new osg::Group();
_viewer->realize();
_viewer->addEventHandler(new osgViewer::StatsHandler);
_viewer->addEventHandler(new osgGA::StateSetManipulator(_viewer->getCamera()->getOrCreateStateSet()));
_viewer->addEventHandler(new osgViewer::ThreadingHandler);
_viewer->addEventHandler(new osgViewer::LODScaleHandler);
_manipulator = new osgGA::KeySwitchMatrixManipulator;
_manipulator->addMatrixManipulator( '1', "Trackball", new osgGA::TrackballManipulator() );
_manipulator->addMatrixManipulator( '2', "Flight", new osgGA::FlightManipulator() );
_manipulator->addMatrixManipulator( '3', "Drive", new osgGA::DriveManipulator() );
_manipulator->addMatrixManipulator( '4', "Terrain", new osgGA::TerrainManipulator() );
_manipulator->addMatrixManipulator( '5', "Orbit", new osgGA::OrbitManipulator() );
_manipulator->addMatrixManipulator( '6', "FirstPerson", new osgGA::FirstPersonManipulator() );
_manipulator->addMatrixManipulator( '7', "Spherical", new osgGA::SphericalManipulator() );
_viewer->setCameraManipulator( _manipulator.get() );
_viewer->getViewerStats()->collectStats("scene", true);
_initialized = true;
}
//Draw
void OsgMainApp::draw(){
//Every load o remove has to be done before any drawing
loadModels();
deleteModels();
_viewer->frame();
}
//Events
void OsgMainApp::mouseButtonPressEvent(float x,float y,int button){
_viewer->getEventQueue()->mouseButtonPress(x, y, button);
}
void OsgMainApp::mouseButtonReleaseEvent(float x,float y,int button){
_viewer->getEventQueue()->mouseButtonRelease(x, y, button);
}
void OsgMainApp::mouseMoveEvent(float x,float y){
_viewer->getEventQueue()->mouseMotion(x, y);
}
void OsgMainApp::keyboardDown(int key){
_viewer->getEventQueue()->keyPress(key);
}
void OsgMainApp::keyboardUp(int key){
_viewer->getEventQueue()->keyRelease(key);
}
//Loading and unloading
void OsgMainApp::loadObject(std::string filePath){
Model newModel;
newModel.filename = filePath;
newModel.name = filePath;
int num = 0;
for(unsigned int i=0;i<_vModels.size();i++){
if(_vModels[i].name==newModel.name)
return;
}
_vModelsToLoad.push_back(newModel);
}
void OsgMainApp::loadObject(std::string name,std::string filePath){
Model newModel;
newModel.filename = filePath;
newModel.name = name;
for(unsigned int i=0;i<_vModels.size();i++){
if(_vModels[i].name==newModel.name){
osg::notify(osg::ALWAYS)<<"Name already used"<<std::endl;
return;
}
}
_vModelsToLoad.push_back(newModel);
}
void OsgMainApp::unLoadObject(int number){
if(_vModels.size() <= number){
osg::notify(osg::FATAL)<<"Index number error"<<std::endl;
return;
}
Model modelToDelete = _vModels[number];
_vModels.erase(_vModels.begin()+number);
_vModelsToDelete.push_back(modelToDelete);
}
void OsgMainApp::clearScene(){
_vModelsToDelete = _vModels;
_vModels.clear();
}
//Other Functions
int OsgMainApp::getNumberObjects(){
return _vModels.size();
}
std::string OsgMainApp::getObjectName(int number){
return _vModels[number].name;
}
void OsgMainApp::setClearColor(osg::Vec4f color){
osg::notify(osg::ALWAYS)<<"Setting Clear Color"<<std::endl;
_viewer->getCamera()->setClearColor(color);
}
osg::Vec4f OsgMainApp::getClearColor(){
osg::notify(osg::ALWAYS)<<"Getting Clear Color"<<std::endl;
return _viewer->getCamera()->getClearColor();
}

View File

@ -0,0 +1,182 @@
/*
* OsgMainApp.hpp
*
* Created on: 29/05/2011
* Author: Jorge Izquierdo Ciges
*/
#ifndef OSGMAINAPP_HPP_
#define OSGMAINAPP_HPP_
//Android log
#include <android/log.h>
#include <iostream>
#include <cstdlib>
#include <math.h>
//Standard libraries
#include <string>
//osg
#include <osg/GL>
#include <osg/GLExtensions>
#include <osg/Depth>
#include <osg/Program>
#include <osg/Shader>
#include <osg/Node>
#include <osg/Notify>
//osgText
#include <osgText/Text>
//osgDB
#include <osgDB/DatabasePager>
#include <osgDB/Registry>
#include <osgDB/ReadFile>
#include <osgDB/WriteFile>
//osg_viewer
#include <osgViewer/Viewer>
#include <osgViewer/Renderer>
#include <osgViewer/ViewerEventHandlers>
//osgGA
#include <osgGA/GUIEventAdapter>
#include <osgGA/MultiTouchTrackballManipulator>
#include <osgGA/TrackballManipulator>
#include <osgGA/FlightManipulator>
#include <osgGA/DriveManipulator>
#include <osgGA/KeySwitchMatrixManipulator>
#include <osgGA/StateSetManipulator>
#include <osgGA/AnimationPathManipulator>
#include <osgGA/TerrainManipulator>
#include <osgGA/SphericalManipulator>
//Self headers
#include "OsgAndroidNotifyHandler.hpp"
//Static plugins Macro
USE_OSGPLUGIN(ive)
USE_OSGPLUGIN(osg)
USE_OSGPLUGIN(osg2)
USE_OSGPLUGIN(terrain)
USE_OSGPLUGIN(rgb)
USE_OSGPLUGIN(OpenFlight)
USE_OSGPLUGIN(dds)
//Static DOTOSG
USE_DOTOSGWRAPPER_LIBRARY(osg)
USE_DOTOSGWRAPPER_LIBRARY(osgFX)
USE_DOTOSGWRAPPER_LIBRARY(osgParticle)
USE_DOTOSGWRAPPER_LIBRARY(osgTerrain)
USE_DOTOSGWRAPPER_LIBRARY(osgText)
USE_DOTOSGWRAPPER_LIBRARY(osgViewer)
USE_DOTOSGWRAPPER_LIBRARY(osgVolume)
//Static serializer
USE_SERIALIZER_WRAPPER_LIBRARY(osg)
USE_SERIALIZER_WRAPPER_LIBRARY(osgAnimation)
USE_SERIALIZER_WRAPPER_LIBRARY(osgFX)
USE_SERIALIZER_WRAPPER_LIBRARY(osgManipulator)
USE_SERIALIZER_WRAPPER_LIBRARY(osgParticle)
USE_SERIALIZER_WRAPPER_LIBRARY(osgTerrain)
USE_SERIALIZER_WRAPPER_LIBRARY(osgText)
USE_SERIALIZER_WRAPPER_LIBRARY(osgVolume)
#define LOG_TAG "osgNativeLib"
#define LOGI(...) __android_log_print(ANDROID_LOG_INFO,LOG_TAG,__VA_ARGS__)
#define LOGE(...) __android_log_print(ANDROID_LOG_ERROR,LOG_TAG,__VA_ARGS__)
struct Model{
std::string filename;
std::string name;
};
static const char gVertexShader[] =
"varying vec4 color; \n"
"const vec3 lightPos =vec3(0.0, 0.0, 10.0); \n"
"const vec4 cessnaColor =vec4(0.8, 0.8, 0.8, 1.0); \n"
"const vec4 lightAmbient =vec4(0.1, 0.1, 0.1, 1.0); \n"
"const vec4 lightDiffuse =vec4(0.4, 0.4, 0.4, 1.0); \n"
"const vec4 lightSpecular =vec4(0.8, 0.8, 0.8, 1.0); \n"
"void DirectionalLight(in vec3 normal, \n"
" in vec3 ecPos, \n"
" inout vec4 ambient, \n"
" inout vec4 diffuse, \n"
" inout vec4 specular) \n"
"{ \n"
" float nDotVP; \n"
" vec3 L = normalize(gl_ModelViewMatrix*vec4(lightPos, 0.0)).xyz; \n"
" nDotVP = max(0.0, dot(normal, L)); \n"
" \n"
" if (nDotVP > 0.0) { \n"
" vec3 E = normalize(-ecPos); \n"
" vec3 R = normalize(reflect( L, normal )); \n"
" specular = pow(max(dot(R, E), 0.0), 16.0) * lightSpecular; \n"
" } \n"
" ambient = lightAmbient; \n"
" diffuse = lightDiffuse * nDotVP; \n"
"} \n"
"void main() { \n"
" vec4 ambiCol = vec4(0.0); \n"
" vec4 diffCol = vec4(0.0); \n"
" vec4 specCol = vec4(0.0); \n"
" gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex; \n"
" vec3 normal = normalize(gl_NormalMatrix * gl_Normal); \n"
" vec4 ecPos = gl_ModelViewMatrix * gl_Vertex; \n"
" DirectionalLight(normal, ecPos.xyz, ambiCol, diffCol, specCol); \n"
" color = cessnaColor * (ambiCol + diffCol + specCol); \n"
"} \n";
static const char gFragmentShader[] =
"precision mediump float; \n"
"varying mediump vec4 color; \n"
"void main() { \n"
" gl_FragColor = color; \n"
"} \n";
class OsgMainApp{
private:
osg::ref_ptr<osgViewer::Viewer> _viewer;
osg::ref_ptr<osg::Group> _root;
osg::ref_ptr<osg::StateSet> _state;
osg::ref_ptr<osgGA::KeySwitchMatrixManipulator> _manipulator;
float _lodScale;
unsigned int _prevFrame;
bool _initialized;
bool _clean_scene;
OsgAndroidNotifyHandler *_notifyHandler;
std::vector<Model> _vModels;
std::vector<Model> _vModelsToLoad;
std::vector<Model> _vModelsToDelete;
void loadModels();
void deleteModels();
public:
OsgMainApp();
~OsgMainApp();
//Initialization function
void initOsgWindow(int x,int y,int width,int height);
//Draw
void draw();
//Events
void mouseButtonPressEvent(float x,float y,int button);
void mouseButtonReleaseEvent(float x,float y,int button);
void mouseMoveEvent(float x,float y);
void keyboardDown(int key);
void keyboardUp(int key);
//Loading and unloading
void loadObject(std::string filePath);
void loadObject(std::string name,std::string filePath);
void unLoadObject(int number);
void clearScene();
//Other functions
int getNumberObjects();
std::string getObjectName(int nunmber);
void setClearColor(osg::Vec4f color);
osg::Vec4f getClearColor();
};
#endif /* OSGMAINAPP_HPP_ */

View File

@ -0,0 +1,113 @@
#include <string.h>
#include <jni.h>
#include <android/log.h>
#include <iostream>
#include "OsgMainApp.hpp"
OsgMainApp mainApp;
extern "C" {
JNIEXPORT void JNICALL Java_osg_AndroidExample_osgNativeLib_init(JNIEnv * env, jobject obj, jint width, jint height);
JNIEXPORT void JNICALL Java_osg_AndroidExample_osgNativeLib_step(JNIEnv * env, jobject obj);
JNIEXPORT void JNICALL Java_osg_AndroidExample_osgNativeLib_clearContents(JNIEnv * env, jobject obj);
JNIEXPORT void JNICALL Java_osg_AndroidExample_osgNativeLib_mouseButtonPressEvent(JNIEnv * env, jobject obj, jfloat x, jfloat y, jint button);
JNIEXPORT void JNICALL Java_osg_AndroidExample_osgNativeLib_mouseButtonReleaseEvent(JNIEnv * env, jobject obj, jfloat x, jfloat y, jint button);
JNIEXPORT void JNICALL Java_osg_AndroidExample_osgNativeLib_mouseMoveEvent(JNIEnv * env, jobject obj, jfloat x, jfloat y);
JNIEXPORT void JNICALL Java_osg_AndroidExample_osgNativeLib_keyboardDown(JNIEnv * env, jobject obj, jint key);
JNIEXPORT void JNICALL Java_osg_AndroidExample_osgNativeLib_keyboardUp(JNIEnv * env, jobject obj, jint key);
JNIEXPORT jintArray JNICALL Java_osg_AndroidExample_osgNativeLib_getClearColor(JNIEnv * env, jobject obj);
JNIEXPORT void JNICALL Java_osg_AndroidExample_osgNativeLib_setClearColor(JNIEnv * env, jobject obj, jint red, jint green, jint blue);
JNIEXPORT void JNICALL Java_osg_AndroidExample_osgNativeLib_loadObject(JNIEnv * env, jobject obj, jstring address);
JNIEXPORT void JNICALL Java_osg_AndroidExample_osgNativeLib_unLoadObject(JNIEnv * env, jobject obj, jint number);
JNIEXPORT jobjectArray JNICALL Java_osg_AndroidExample_osgNativeLib_getObjectNames(JNIEnv * env, jobject obj);
};
JNIEXPORT void JNICALL Java_osg_AndroidExample_osgNativeLib_init(JNIEnv * env, jobject obj, jint width, jint height){
mainApp.initOsgWindow(0,0,width,height);
}
JNIEXPORT void JNICALL Java_osg_AndroidExample_osgNativeLib_step(JNIEnv * env, jobject obj){
mainApp.draw();
}
JNIEXPORT void JNICALL Java_osg_AndroidExample_osgNativeLib_clearContents(JNIEnv * env, jobject obj){
mainApp.clearScene();
}
JNIEXPORT void JNICALL Java_osg_AndroidExample_osgNativeLib_mouseButtonPressEvent(JNIEnv * env, jobject obj, jfloat x, jfloat y, jint button){
mainApp.mouseButtonPressEvent(x,y,button);
}
JNIEXPORT void JNICALL Java_osg_AndroidExample_osgNativeLib_mouseButtonReleaseEvent(JNIEnv * env, jobject obj, jfloat x, jfloat y, jint button){
mainApp.mouseButtonReleaseEvent(x,y,button);
}
JNIEXPORT void JNICALL Java_osg_AndroidExample_osgNativeLib_mouseMoveEvent(JNIEnv * env, jobject obj, jfloat x, jfloat y){
mainApp.mouseMoveEvent(x,y);
}
JNIEXPORT void JNICALL Java_osg_AndroidExample_osgNativeLib_keyboardDown(JNIEnv * env, jobject obj, jint key){
mainApp.keyboardDown(key);
}
JNIEXPORT void JNICALL Java_osg_AndroidExample_osgNativeLib_keyboardUp(JNIEnv * env, jobject obj, jint key){
mainApp.keyboardUp(key);
}
JNIEXPORT jintArray JNICALL Java_osg_AndroidExample_osgNativeLib_getClearColor(JNIEnv * env, jobject obj){
jintArray color;
color = env->NewIntArray(3);
if (color == NULL) {
return NULL;
}
osg::Vec4 vTemp1 = mainApp.getClearColor();
jint vTemp2[3];
vTemp2[0] = (int) (vTemp1.r() * 255);
vTemp2[1] = (int) (vTemp1.g() * 255);
vTemp2[2] = (int) (vTemp1.b() * 255);
std::cout<<vTemp2[0]<<" "<<vTemp2[1]<<" "<<vTemp2[2]<<" "<<std::endl;
env->SetIntArrayRegion(color, 0, 3, vTemp2);
return color;
}
JNIEXPORT void JNICALL Java_osg_AndroidExample_osgNativeLib_setClearColor(JNIEnv * env, jobject obj, jint red, jint green, jint blue){
osg::Vec4 tVec((float) red / 255.0f, (float) green / 255.0f, (float) blue / 255.0f, 0.0f);
mainApp.setClearColor(tVec);
}
JNIEXPORT void JNICALL Java_osg_AndroidExample_osgNativeLib_loadObject(JNIEnv * env, jobject obj, jstring address){
//Import Strings from JNI
const char *nativeAddress = env->GetStringUTFChars(address, JNI_FALSE);
mainApp.loadObject(std::string(nativeAddress));
//Release Strings to JNI
env->ReleaseStringUTFChars(address, nativeAddress);
}
JNIEXPORT void JNICALL Java_osg_AndroidExample_osgNativeLib_loadObject(JNIEnv * env, jobject obj, jstring address, jstring name){
//Import Strings from JNI
const char *nativeAddress = env->GetStringUTFChars(address,JNI_FALSE);
const char *nativeName = env->GetStringUTFChars(name, JNI_FALSE);
mainApp.loadObject(std::string(nativeName),std::string(nativeAddress));
//Release Strings to JNI
env->ReleaseStringUTFChars(address, nativeAddress);
env->ReleaseStringUTFChars(address, nativeName);
}
JNIEXPORT void JNICALL Java_osg_AndroidExample_osgNativeLib_unLoadObject(JNIEnv * env, jobject obj, jint number){
mainApp.unLoadObject(number);
}
JNIEXPORT jobjectArray JNICALL Java_osg_AndroidExample_osgNativeLib_getObjectNames(JNIEnv * env, jobject obj){
jobjectArray fileNames;
unsigned int numModels = mainApp.getNumberObjects();
fileNames = (jobjectArray)env->NewObjectArray(numModels,env->FindClass("java/lang/String"),env->NewStringUTF(""));
for(unsigned int i=0;i < numModels;i++){
std::string name = mainApp.getObjectName(i);
env->SetObjectArrayElement(fileNames,i,env->NewStringUTF(name.c_str()));
}
return fileNames;
}

View File

@ -0,0 +1,36 @@
-optimizationpasses 5
-dontusemixedcaseclassnames
-dontskipnonpubliclibraryclasses
-dontpreverify
-verbose
-optimizations !code/simplification/arithmetic,!field/*,!class/merging/*
-keep public class * extends android.app.Activity
-keep public class * extends android.app.Application
-keep public class * extends android.app.Service
-keep public class * extends android.content.BroadcastReceiver
-keep public class * extends android.content.ContentProvider
-keep public class * extends android.app.backup.BackupAgentHelper
-keep public class * extends android.preference.Preference
-keep public class com.android.vending.licensing.ILicensingService
-keepclasseswithmembernames class * {
native <methods>;
}
-keepclasseswithmembernames class * {
public <init>(android.content.Context, android.util.AttributeSet);
}
-keepclasseswithmembernames class * {
public <init>(android.content.Context, android.util.AttributeSet, int);
}
-keepclassmembers enum * {
public static **[] values();
public static ** valueOf(java.lang.String);
}
-keep class * implements android.os.Parcelable {
public static final android.os.Parcelable$Creator *;
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.5 KiB

View File

@ -0,0 +1,29 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="wrap_content">
<TextView
android:id="@+id/uiTextEntryText"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="20dip"
android:layout_marginRight="20dip"
android:text="@string/uiTextEntryText"
android:gravity="left"
/>
<EditText
android:id="@+id/uiEditTextInput"
android:layout_height="wrap_content"
android:layout_width="fill_parent"
android:layout_marginLeft="20dip"
android:layout_marginRight="20dip"
android:scrollHorizontally="true"
android:autoText="false"
android:capitalize="none"
android:gravity="fill_horizontal"
/>
</LinearLayout>

View File

@ -0,0 +1,12 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
>
<TextView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="@string/hello"
/>
</LinearLayout>

View File

@ -0,0 +1,45 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:background="@color/uiControlBar"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<FrameLayout
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_weight="1">
<osg.AndroidExample.EGLview android:id="@+id/surfaceGLES"
android:visibility="visible"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
/>
</FrameLayout>
<RelativeLayout android:id="@+id/uiNavigation"
android:gravity="center"
android:layout_width="fill_parent"
android:layout_height="wrap_content">
<LinearLayout
android:layout_centerInParent="true"
android:orientation="horizontal"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="center">
<Button android:id="@+id/uiButtonLight"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/uiButtonLight"/>
<Button android:id="@+id/uiButtonCenter"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/uiButtonCenter"/>
<Button android:id="@+id/uiButtonChangeNavigation"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/uiButtonChangeNavigation"/>
</LinearLayout>
</RelativeLayout>
</LinearLayout>

View File

@ -0,0 +1,9 @@
<?xml version="1.0" encoding="utf-8"?>
<menu
xmlns:android="http://schemas.android.com/apk/res/android">
<item android:id="@+id/menuLoadObject" android:title="@string/menuLoadObject" android:titleCondensed="@string/menuLoadObjectCondensed"></item>
<item android:id="@+id/menuDeleteObject" android:title="@string/menuDeleteObject" android:titleCondensed="@string/menuDeleteObjectCondensed"></item>
<item android:id="@+id/menuCleanScene" android:title="@string/menuCleanScene" android:titleCondensed="@string/menuCleanSceneCondensed"></item>
<item android:id="@+id/menuChangeBackground" android:title="@string/menuChangeBackground" android:titleCondensed="@string/menuChangeBackgroundCondensed"></item>
<item android:id="@+id/menuShowKeyboard" android:title="@string/menuShowKeyboard" android:titleCondensed="@string/menuShowKeyboardCondensed"></item>
</menu>

View File

@ -0,0 +1,28 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="hello">Hello World, osgViewer!</string>
<string name="app_name">osgAndroidExample</string>
<color name="uiControlBar">#BBBBBB</color>
<string name="uiButtonLight">Light (ON/OFF)</string>
<string name="uiButtonCenter">Center View</string>
<string name="uiButtonChangeNavigation">Change Navigation</string>
<string name="uiTextEntryText">Write address</string>
<string name="uiToastNavPrincipal">Main navigation</string>
<string name="uiToastNavSecond">Second Navigation</string>
<string name="uiToastLightOn">Light ON</string>
<string name="uiToastLightOff">Light OFF</string>
<string name="menuLoadObject">Load Object</string>
<string name="menuLoadObjectCondensed">L. Object</string>
<string name="menuDeleteObject">Delete Object</string>
<string name="menuDeleteObjectCondensed">D. Object</string>
<string name="menuCleanScene">Clean Scene</string>
<string name="menuCleanSceneCondensed">Clean</string>
<string name="menuChangeBackground">Change Background</string>
<string name="menuChangeBackgroundCondensed">C.Background</string>
<string name="menuShowKeyboard">Show Keyboard</string>
<string name="menuShowKeyboardCondensed">S.Keyboard</string>
<string name="uiDialogTextChoseRemove">Select Object</string>
<string name="uiDialogTextAddress">Write file address</string>
<string name="uiDialogOk">Accept</string>
<string name="uiDialogCancel">Cancel</string>
</resources>

View File

@ -0,0 +1,250 @@
package osg.AndroidExample;
import android.app.Dialog;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.LinearGradient;
import android.graphics.Paint;
import android.graphics.Shader;
import android.os.Bundle;
import android.view.MotionEvent;
import android.view.View;
public class ColorPickerDialog extends Dialog{
public interface OnColorChangeListener{
void colorChange(int color);
}
private OnColorChangeListener tListener;
private int tInitialColor;
private static class ColorPickerView extends View{
private Paint tPaint;
private float tCurrentHue = 0;
private int tCurrentX = 0;
private int tCurrentY = 0;
private int tCurrentColor;
private final int[] tHueGradientColors = new int [258];
private int [] tGradientColors = new int[65536]; //256X256 colors
private OnColorChangeListener tListener;
private boolean tQSelected = false;
public ColorPickerView(Context context, OnColorChangeListener listener, int color) {
super(context);
// TODO Auto-generated constructor stub
tListener = listener;
//Get Hue from tCurrentColor and update the Gradient of Color
float[] newHSV = new float[3];
Color.colorToHSV(color, newHSV);
tCurrentHue = newHSV[0];
updateGradientColors();
tCurrentColor = color;
//Initialize of colors in Hue slider
int index = 0;
for(float i=0; i<256; i += 256/42 , index++){
tHueGradientColors[index] = Color.rgb(255, 0, (int)i);
}
for(float i=0; i<256; i += 256/42 , index++){
tHueGradientColors[index] = Color.rgb(255-(int)i, 0, 255);
}
for(float i=0; i<256; i += 256/42 , index++){
tHueGradientColors[index] = Color.rgb(0, (int) i, 255);
}
for(float i=0; i<256; i += 256/42 , index++){
tHueGradientColors[index] = Color.rgb(0, 255, 255-(int)i);
}
for(float i=0; i<256; i += 256/42 , index++){
tHueGradientColors[index] = Color.rgb((int)i, 255, 0);
}
for(float i=0; i<256; i += 256/42 , index++){
tHueGradientColors[index] = Color.rgb(255, 255-(int)i, 0);
}
// Paint initialized
tPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
tPaint.setTextAlign(Paint.Align.CENTER);
tPaint.setTextSize(12);
}
// Get the Color from Hue Bar
private int getCurrentGradientColor(){
int currentHue = 255 - (int)(tCurrentHue*255/360);
int index = 0;
for (float i=0; i<256; i += 256/42, index++){
if (index == currentHue) return Color.rgb(255, 0, (int) i );
}
for (float i=0; i<256; i += 256/42, index++){
if (index == currentHue) return Color.rgb(255-(int)i, 0, 255 );
}
for (float i=0; i<256; i += 256/42, index++){
if (index == currentHue) return Color.rgb(0, (int) i, 255 );
}
for (float i=0; i<256; i += 256/42, index++){
if (index == currentHue) return Color.rgb(0, 255, 255-(int) i );
}
for (float i=0; i<256; i += 256/42, index++){
if (index == currentHue) return Color.rgb((int) i, 255, 0 );
}
for (float i=0; i<256; i += 256/42, index++){
if (index == currentHue) return Color.rgb(255, 255-(int) i, 0);
}
return Color.RED;
}
private void updateGradientColors(){
int actualColor = getCurrentGradientColor();
int index = 0;
int[] colColors = new int[256];
for(int y=0; y<256; y++){
for(int x=0; x<256; x++ , index++){
if(y==0){
tGradientColors[index] = Color.rgb(255-(255-Color.red(actualColor))*x/255, 255-(255-Color.green(actualColor))*x/255, 255-(255-Color.blue(actualColor))*x/255);
colColors[x] = tGradientColors[index];
}
else{
tGradientColors[index] = Color.rgb((255-y)*Color.red(colColors[x])/255, (255-y)*Color.green(colColors[x])/255, (255-y)*Color.blue(colColors[x])/255);
}
}
}
}
@Override
protected void onDraw(Canvas canvas){
int translatedHue = 255 - (int)(tCurrentHue*255/360);
//Display HUE with bar lines
for(int x=0; x<256; x++){
//We display the color or a big white bar
if(translatedHue != x){
tPaint.setColor(tHueGradientColors[x]);
tPaint.setStrokeWidth(1);
}
else{
tPaint.setColor(Color.WHITE);
tPaint.setStrokeWidth(3);
}
canvas.drawLine(x+10, 0, x+10, 40, tPaint);
}
// Display Gradient Box
for(int x=0; x<256;x++){
int[] colors = new int[2];
colors[0] = tGradientColors[x];
colors[1] = Color.BLACK;
Shader shader = new LinearGradient(0,50,0,306,colors,null, Shader.TileMode.REPEAT);
tPaint.setShader(shader);
canvas.drawLine(x+10, 50, x+10, 306, tPaint);
}
tPaint.setShader(null);
//Display the circle around the currently selected color in the main field
if(tCurrentX !=0 && tCurrentY != 0){
tPaint.setStyle(Paint.Style.STROKE);
tPaint.setColor(Color.BLACK);
canvas.drawCircle(tCurrentX, tCurrentY, 10, tPaint);
}
//Draw a button
tPaint.setStyle(Paint.Style.FILL);
if(tQSelected){
tPaint.setColor(Color.WHITE);
canvas.drawCircle(138, 336, 30, tPaint);
}
tPaint.setColor(tCurrentColor);
canvas.drawCircle(138, 336, 20, tPaint);
}
@Override
protected void onMeasure(int width,int height){
setMeasuredDimension(276, 366);
}
@Override
public boolean onTouchEvent(MotionEvent event){
if(event.getAction() != MotionEvent.ACTION_DOWN && event.getAction() != MotionEvent.ACTION_MOVE && event.getAction() != MotionEvent.ACTION_UP) return true;
float x = event.getX();
float y = event.getY();
tQSelected=false;
// if in Hue Bar
if(x >10 && x <266 && y>0 && y<40){
//Update gradient
tCurrentHue = (255-x)*360/255;
updateGradientColors();
//Update current Selected Color
int nX = tCurrentX-10;
int nY = tCurrentY-60;
int index = 256 * (nY-1)+nX;
if(index>0 && index < tGradientColors.length)
tCurrentColor = tGradientColors[256*(nY-1)+nX];
invalidate(); //By invalidating we are forcing a redraw;
}
// If Main gradient
if ( x >10 && x< 266 && y>50 && y <306){
tCurrentX = (int) x;
tCurrentY = (int) y;
int nX = tCurrentX - 10;
int nY = tCurrentY - 60;
int index = 256*(nY-1)+nX;
if (index >0 && index < tGradientColors.length){
tCurrentColor = tGradientColors[index];
invalidate(); //By invalidating we are forcing a redraw;
}
}
if( x>118 && x<158 && y > 316 && y <356){
if(event.getAction() == MotionEvent.ACTION_DOWN || event.getAction() == MotionEvent.ACTION_MOVE){
tQSelected=true;
}
if(event.getAction() == MotionEvent.ACTION_UP){
tQSelected=false;
tListener.colorChange(tCurrentColor);
}
invalidate();
}
return true;
}
}
public ColorPickerDialog(Context context, OnColorChangeListener listener, int initialColor){
super(context);
tListener = listener;
tInitialColor = initialColor;
}
@Override
protected void onCreate( Bundle savedInstanceState){
super.onCreate(savedInstanceState);
OnColorChangeListener l = new OnColorChangeListener(){
public void colorChange(int color){
tListener.colorChange(color);
dismiss();
}
};
setContentView(new ColorPickerView(getContext(),l,tInitialColor));
}
}

View File

@ -0,0 +1,329 @@
package osg.AndroidExample;
/*
* Copyright (C) 2008 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import android.app.Dialog;
import android.content.Context;
import android.graphics.PixelFormat;
import android.opengl.GLSurfaceView;
import android.util.AttributeSet;
import android.util.Log;
import android.view.*;
import javax.microedition.khronos.egl.EGL10;
import javax.microedition.khronos.egl.EGLConfig;
import javax.microedition.khronos.egl.EGLContext;
import javax.microedition.khronos.egl.EGLDisplay;
import javax.microedition.khronos.opengles.GL10;
/**
* A simple GLSurfaceView sub-class that demonstrate how to perform
* OpenGL ES 1.0 rendering into a GL Surface. Note the following important
* details:
*
* - The class must use a custom context factory to enable 1.0 rendering.
* See ContextFactory class definition below.
*
* - The class must use a custom EGLConfigChooser to be able to select
* an EGLConfig that supports 1.0. This is done by providing a config
* specification to eglChooseConfig() that has the attribute
* EGL10.ELG_RENDERABLE_TYPE containing the EGL_OPENGL_ES_BIT flag
* set. See ConfigChooser class definition below.
*
* - The class must select the surface's format, then choose an EGLConfig
* that matches it exactly (with regards to red/green/blue/alpha channels
* bit depths). Failure to do so would result in an EGL_BAD_MATCH error.
*/
public class EGLview extends GLSurfaceView {
private static String TAG = "EGLview";
private static final boolean DEBUG = false;
public EGLview(Context context) {
super(context);
init(false, 16, 8);
}
public EGLview(Context context, AttributeSet attrs) {
super(context,attrs);
init(false, 16, 8);
}
public EGLview(Context context, boolean translucent, int depth, int stencil) {
super(context);
init(translucent, depth, stencil);
}
private void init(boolean translucent, int depth, int stencil) {
/* By default, GLSurfaceView() creates a RGB_565 opaque surface.
* If we want a translucent one, we should change the surface's
* format here, using PixelFormat.TRANSLUCENT for GL Surfaces
* is interpreted as any 32-bit surface with alpha by SurfaceFlinger.
*/
if (translucent) {
this.getHolder().setFormat(PixelFormat.TRANSLUCENT);
}
/* Setup the context factory for 2.0 rendering.
* See ContextFactory class definition below
*/
setEGLContextFactory(new ContextFactory());
/* We need to choose an EGLConfig that matches the format of
* our surface exactly. This is going to be done in our
* custom config chooser. See ConfigChooser class definition
* below.
*/
setEGLConfigChooser( translucent ?
new ConfigChooser(8, 8, 8, 8, depth, stencil) :
new ConfigChooser(5, 6, 5, 0, depth, stencil) );
/* Set the renderer responsible for frame rendering */
setRenderer(new Renderer());
}
private static class ContextFactory implements GLSurfaceView.EGLContextFactory {
private static int EGL_CONTEXT_CLIENT_VERSION = 0x3098;
public EGLContext createContext(EGL10 egl, EGLDisplay display, EGLConfig eglConfig) {
Log.w(TAG, "creating OpenGL ES 2.0 context");
checkEglError("Before eglCreateContext", egl);
int[] attrib_list = {EGL_CONTEXT_CLIENT_VERSION, 2, EGL10.EGL_NONE };
EGLContext context = egl.eglCreateContext(display, eglConfig, EGL10.EGL_NO_CONTEXT, attrib_list);
checkEglError("After eglCreateContext", egl);
return context;
}
public void destroyContext(EGL10 egl, EGLDisplay display, EGLContext context) {
egl.eglDestroyContext(display, context);
}
}
private static void checkEglError(String prompt, EGL10 egl) {
int error;
while ((error = egl.eglGetError()) != EGL10.EGL_SUCCESS) {
Log.e(TAG, String.format("%s: EGL error: 0x%x", prompt, error));
}
}
private static class ConfigChooser implements GLSurfaceView.EGLConfigChooser {
public ConfigChooser(int r, int g, int b, int a, int depth, int stencil) {
mRedSize = r;
mGreenSize = g;
mBlueSize = b;
mAlphaSize = a;
mDepthSize = depth;
mStencilSize = stencil;
}
/* This EGL config specification is used to specify 1.x rendering.
* We use a minimum size of 4 bits for red/green/blue, but will
* perform actual matching in chooseConfig() below.
*/
private static int EGL_OPENGL_ES_BIT = 4;
private static int[] s_configAttribs2 =
{
EGL10.EGL_RED_SIZE, 4,
EGL10.EGL_GREEN_SIZE, 4,
EGL10.EGL_BLUE_SIZE, 4,
EGL10.EGL_RENDERABLE_TYPE, EGL_OPENGL_ES_BIT,
EGL10.EGL_NONE
};
public EGLConfig chooseConfig(EGL10 egl, EGLDisplay display) {
/* Get the number of minimally matching EGL configurations
*/
int[] num_config = new int[1];
egl.eglChooseConfig(display, s_configAttribs2, null, 0, num_config);
int numConfigs = num_config[0];
if (numConfigs <= 0) {
throw new IllegalArgumentException("No configs match configSpec");
}
/* Allocate then read the array of minimally matching EGL configs
*/
EGLConfig[] configs = new EGLConfig[numConfigs];
egl.eglChooseConfig(display, s_configAttribs2, configs, numConfigs, num_config);
if (DEBUG) {
printConfigs(egl, display, configs);
}
/* Now return the "best" one
*/
return chooseConfig(egl, display, configs);
}
public EGLConfig chooseConfig(EGL10 egl, EGLDisplay display,
EGLConfig[] configs) {
for(EGLConfig config : configs) {
int d = findConfigAttrib(egl, display, config,
EGL10.EGL_DEPTH_SIZE, 0);
int s = findConfigAttrib(egl, display, config,
EGL10.EGL_STENCIL_SIZE, 0);
// We need at least mDepthSize and mStencilSize bits
if (d < mDepthSize || s < mStencilSize)
continue;
// We want an *exact* match for red/green/blue/alpha
int r = findConfigAttrib(egl, display, config,
EGL10.EGL_RED_SIZE, 0);
int g = findConfigAttrib(egl, display, config,
EGL10.EGL_GREEN_SIZE, 0);
int b = findConfigAttrib(egl, display, config,
EGL10.EGL_BLUE_SIZE, 0);
int a = findConfigAttrib(egl, display, config,
EGL10.EGL_ALPHA_SIZE, 0);
if (r == mRedSize && g == mGreenSize && b == mBlueSize && a == mAlphaSize)
return config;
}
return null;
}
private int findConfigAttrib(EGL10 egl, EGLDisplay display,
EGLConfig config, int attribute, int defaultValue) {
if (egl.eglGetConfigAttrib(display, config, attribute, mValue)) {
return mValue[0];
}
return defaultValue;
}
private void printConfigs(EGL10 egl, EGLDisplay display,
EGLConfig[] configs) {
int numConfigs = configs.length;
Log.w(TAG, String.format("%d configurations", numConfigs));
for (int i = 0; i < numConfigs; i++) {
Log.w(TAG, String.format("Configuration %d:\n", i));
printConfig(egl, display, configs[i]);
}
}
private void printConfig(EGL10 egl, EGLDisplay display,
EGLConfig config) {
int[] attributes = {
EGL10.EGL_BUFFER_SIZE,
EGL10.EGL_ALPHA_SIZE,
EGL10.EGL_BLUE_SIZE,
EGL10.EGL_GREEN_SIZE,
EGL10.EGL_RED_SIZE,
EGL10.EGL_DEPTH_SIZE,
EGL10.EGL_STENCIL_SIZE,
EGL10.EGL_CONFIG_CAVEAT,
EGL10.EGL_CONFIG_ID,
EGL10.EGL_LEVEL,
EGL10.EGL_MAX_PBUFFER_HEIGHT,
EGL10.EGL_MAX_PBUFFER_PIXELS,
EGL10.EGL_MAX_PBUFFER_WIDTH,
EGL10.EGL_NATIVE_RENDERABLE,
EGL10.EGL_NATIVE_VISUAL_ID,
EGL10.EGL_NATIVE_VISUAL_TYPE,
0x3030, // EGL10.EGL_PRESERVED_RESOURCES,
EGL10.EGL_SAMPLES,
EGL10.EGL_SAMPLE_BUFFERS,
EGL10.EGL_SURFACE_TYPE,
EGL10.EGL_TRANSPARENT_TYPE,
EGL10.EGL_TRANSPARENT_RED_VALUE,
EGL10.EGL_TRANSPARENT_GREEN_VALUE,
EGL10.EGL_TRANSPARENT_BLUE_VALUE,
0x3039, // EGL10.EGL_BIND_TO_TEXTURE_RGB,
0x303A, // EGL10.EGL_BIND_TO_TEXTURE_RGBA,
0x303B, // EGL10.EGL_MIN_SWAP_INTERVAL,
0x303C, // EGL10.EGL_MAX_SWAP_INTERVAL,
EGL10.EGL_LUMINANCE_SIZE,
EGL10.EGL_ALPHA_MASK_SIZE,
EGL10.EGL_COLOR_BUFFER_TYPE,
EGL10.EGL_RENDERABLE_TYPE,
0x3042 // EGL10.EGL_CONFORMANT
};
String[] names = {
"EGL_BUFFER_SIZE",
"EGL_ALPHA_SIZE",
"EGL_BLUE_SIZE",
"EGL_GREEN_SIZE",
"EGL_RED_SIZE",
"EGL_DEPTH_SIZE",
"EGL_STENCIL_SIZE",
"EGL_CONFIG_CAVEAT",
"EGL_CONFIG_ID",
"EGL_LEVEL",
"EGL_MAX_PBUFFER_HEIGHT",
"EGL_MAX_PBUFFER_PIXELS",
"EGL_MAX_PBUFFER_WIDTH",
"EGL_NATIVE_RENDERABLE",
"EGL_NATIVE_VISUAL_ID",
"EGL_NATIVE_VISUAL_TYPE",
"EGL_PRESERVED_RESOURCES",
"EGL_SAMPLES",
"EGL_SAMPLE_BUFFERS",
"EGL_SURFACE_TYPE",
"EGL_TRANSPARENT_TYPE",
"EGL_TRANSPARENT_RED_VALUE",
"EGL_TRANSPARENT_GREEN_VALUE",
"EGL_TRANSPARENT_BLUE_VALUE",
"EGL_BIND_TO_TEXTURE_RGB",
"EGL_BIND_TO_TEXTURE_RGBA",
"EGL_MIN_SWAP_INTERVAL",
"EGL_MAX_SWAP_INTERVAL",
"EGL_LUMINANCE_SIZE",
"EGL_ALPHA_MASK_SIZE",
"EGL_COLOR_BUFFER_TYPE",
"EGL_RENDERABLE_TYPE",
"EGL_CONFORMANT"
};
int[] value = new int[1];
for (int i = 0; i < attributes.length; i++) {
int attribute = attributes[i];
String name = names[i];
if ( egl.eglGetConfigAttrib(display, config, attribute, value)) {
Log.w(TAG, String.format(" %s: %d\n", name, value[0]));
} else {
// Log.w(TAG, String.format(" %s: failed\n", name));
while (egl.eglGetError() != EGL10.EGL_SUCCESS);
}
}
}
// Subclasses can adjust these values:
protected int mRedSize;
protected int mGreenSize;
protected int mBlueSize;
protected int mAlphaSize;
protected int mDepthSize;
protected int mStencilSize;
private int[] mValue = new int[1];
}
private static class Renderer implements GLSurfaceView.Renderer {
public void onDrawFrame(GL10 gl) {
osgNativeLib.step();
}
public void onSurfaceChanged(GL10 gl, int width, int height) {
osgNativeLib.init(width, height);
}
public void onSurfaceCreated(GL10 gl, EGLConfig config) {
// Do nothing
gl.glEnable(GL10.GL_DEPTH_TEST);
}
}
}

View File

@ -0,0 +1,28 @@
package osg.AndroidExample;
public class osgNativeLib {
static {
System.loadLibrary("osgNativeLib");
}
/**
* @param width the current view width
* @param height the current view height
*/
public static native void init(int width, int height);
public static native void step();
public static native void clearContents();
public static native void mouseButtonPressEvent(float x,float y, int button);
public static native void mouseButtonReleaseEvent(float x,float y, int button);
public static native void mouseMoveEvent(float x,float y);
public static native void keyboardDown(int key);
public static native void keyboardUp(int key);
public static native void setClearColor(int red,int green, int blue);
public static native int[] getClearColor();
public static native void loadObject(String address);
public static native void loadObject(String address,String name);
public static native void unLoadObject(int number);
public static native String[] getObjectNames();
}

View File

@ -0,0 +1,417 @@
package osg.AndroidExample;
import android.app.Activity;
import android.app.AlertDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.res.Resources;
import android.graphics.Color;
import android.graphics.PointF;
import android.os.Bundle;
import android.util.FloatMath;
import android.util.Log;
import android.view.KeyEvent;
import android.view.LayoutInflater;
import android.view.MenuItem;
import android.view.MotionEvent;
import android.view.View;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.WindowManager;
import android.view.View.OnClickListener;
import android.view.inputmethod.InputMethodManager;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.Toast;
import android.widget.ImageButton;
import java.io.File;
public class osgViewer extends Activity implements View.OnTouchListener, View.OnKeyListener, ColorPickerDialog.OnColorChangeListener {
enum moveTypes { NONE , DRAG, MDRAG, ZOOM ,ACTUALIZE}
enum navType { PRINCIPAL , SECONDARY }
enum lightType { ON , OFF }
moveTypes mode=moveTypes.NONE;
navType navMode = navType.PRINCIPAL;
lightType lightMode = lightType.ON;
PointF oneFingerOrigin = new PointF(0,0);
long timeOneFinger=0;
PointF twoFingerOrigin = new PointF(0,0);
long timeTwoFinger=0;
float distanceOrigin;
int backgroundColor;
private static final String TAG = "OSG Activity";
//Ui elements
EGLview mView;
Button uiCenterViewButton;
Button uiNavigationChangeButton;
ImageButton uiNavigationLeft;
ImageButton uiNavigationRight;
Button uiLightChangeButton;
//Toasts
Toast msgUiNavPrincipal;
Toast msgUiNavSecondary;
Toast msgUiLightOn;
Toast msgUiLightOff;
//Dialogs
AlertDialog removeLayerDialog;
AlertDialog loadLayerAddress;
//Main Android Activity life cycle
@Override protected void onCreate(Bundle icicle) {
super.onCreate(icicle);
setContentView(R.layout.ui_layout_gles);
//Obtain every Ui element
mView= (EGLview) findViewById(R.id.surfaceGLES);
mView.setOnTouchListener(this);
mView.setOnKeyListener(this);
uiCenterViewButton = (Button) findViewById(R.id.uiButtonCenter);
uiCenterViewButton.setOnClickListener(uiListenerCenterView);
uiNavigationChangeButton = (Button) findViewById(R.id.uiButtonChangeNavigation);
uiNavigationChangeButton.setOnClickListener(uiListenerChangeNavigation);
uiLightChangeButton = (Button) findViewById(R.id.uiButtonLight);
uiLightChangeButton.setOnClickListener(uiListenerChangeLight);
//Creating Toasts
msgUiNavPrincipal = Toast.makeText(getApplicationContext(), R.string.uiToastNavPrincipal, Toast.LENGTH_SHORT);
msgUiNavSecondary = Toast.makeText(getApplicationContext(), R.string.uiToastNavSecond, Toast.LENGTH_SHORT);
msgUiLightOn = Toast.makeText(getApplicationContext(), R.string.uiToastLightOn, Toast.LENGTH_SHORT);
msgUiLightOff = Toast.makeText(getApplicationContext(), R.string.uiToastLightOff, Toast.LENGTH_SHORT);
//Creating Dialogs
LayoutInflater factory = LayoutInflater.from(getApplicationContext());
final View textEntryView = factory.inflate(R.layout.dialog_text_entry, null);
AlertDialog.Builder loadLayerDialogBuilder = new AlertDialog.Builder(this);
loadLayerDialogBuilder.setIcon(R.drawable.web_browser);
loadLayerDialogBuilder.setTitle(R.string.uiDialogTextAddress);
loadLayerDialogBuilder.setView(textEntryView);
loadLayerDialogBuilder.setPositiveButton(R.string.uiDialogOk, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
// TODO Auto-generated method stub
EditText address;
address = (EditText) textEntryView.findViewById(R.id.uiEditTextInput);
osgNativeLib.loadObject(address.getText().toString());
}
});
loadLayerDialogBuilder.setNegativeButton(R.string.uiDialogCancel, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
// TODO Auto-generated method stub
}
});
loadLayerAddress = loadLayerDialogBuilder.create();
}
@Override protected void onPause() {
super.onPause();
mView.onPause();
}
@Override protected void onResume() {
super.onResume();
mView.onResume();
}
//Main view event processing
@Override
public boolean onKey(View v, int keyCode, KeyEvent event) {
return true;
}
@Override
public boolean onKeyDown(int keyCode, KeyEvent event){
//DO NOTHING this will render useless every menu key except Home
int keyChar= event.getUnicodeChar();
osgNativeLib.keyboardDown(keyChar);
return true;
}
@Override
public boolean onKeyUp(int keyCode, KeyEvent event){
switch (keyCode){
case KeyEvent.KEYCODE_BACK:
super.onDestroy();
this.finish();
break;
case KeyEvent.KEYCODE_SEARCH:
break;
case KeyEvent.KEYCODE_MENU:
this.openOptionsMenu();
break;
default:
int keyChar= event.getUnicodeChar();
osgNativeLib.keyboardUp(keyChar);
}
return true;
}
@Override
public boolean onTouch(View v, MotionEvent event) {
//dumpEvent(event);
long time_arrival = event.getEventTime();
int n_points = event.getPointerCount();
int action = event.getAction() & MotionEvent.ACTION_MASK;
switch(n_points){
case 1:
switch(action){
case MotionEvent.ACTION_DOWN:
mode = moveTypes.DRAG;
osgNativeLib.mouseMoveEvent(event.getX(0), event.getY(0));
if(navMode==navType.PRINCIPAL)
osgNativeLib.mouseButtonPressEvent(event.getX(0), event.getY(0), 2);
else
osgNativeLib.mouseButtonPressEvent(event.getX(0), event.getY(0), 1);
oneFingerOrigin.x=event.getX(0);
oneFingerOrigin.y=event.getY(0);
break;
case MotionEvent.ACTION_CANCEL:
switch(mode){
case DRAG:
osgNativeLib.mouseMoveEvent(event.getX(0), event.getY(0));
if(navMode==navType.PRINCIPAL)
osgNativeLib.mouseButtonReleaseEvent(event.getX(0), event.getY(0), 2);
else
osgNativeLib.mouseButtonReleaseEvent(event.getX(0), event.getY(0), 1);
break;
default :
Log.e(TAG,"There has been an anomaly in touch input 1point/action");
}
mode = moveTypes.NONE;
break;
case MotionEvent.ACTION_MOVE:
osgNativeLib.mouseMoveEvent(event.getX(0), event.getY(0));
oneFingerOrigin.x=event.getX(0);
oneFingerOrigin.y=event.getY(0);
break;
case MotionEvent.ACTION_UP:
switch(mode){
case DRAG:
if(navMode==navType.PRINCIPAL)
osgNativeLib.mouseButtonReleaseEvent(event.getX(0), event.getY(0), 2);
else
osgNativeLib.mouseButtonReleaseEvent(event.getX(0), event.getY(0), 1);
break;
default :
Log.e(TAG,"There has been an anomaly in touch input 1 point/action");
}
mode = moveTypes.NONE;
break;
default :
Log.e(TAG,"1 point Action not captured");
}
break;
case 2:
switch (action){
case MotionEvent.ACTION_POINTER_DOWN:
//Free previous Action
switch(mode){
case DRAG:
if(navMode==navType.PRINCIPAL)
osgNativeLib.mouseButtonReleaseEvent(event.getX(0), event.getY(0), 2);
else
osgNativeLib.mouseButtonReleaseEvent(event.getX(0), event.getY(0), 1);
break;
}
mode = moveTypes.ZOOM;
distanceOrigin = sqrDistance(event);
twoFingerOrigin.x=event.getX(1);
twoFingerOrigin.y=event.getY(1);
oneFingerOrigin.x=event.getX(0);
oneFingerOrigin.y=event.getY(0);
osgNativeLib.mouseMoveEvent(oneFingerOrigin.x,oneFingerOrigin.y);
osgNativeLib.mouseButtonPressEvent(oneFingerOrigin.x,oneFingerOrigin.y, 3);
osgNativeLib.mouseMoveEvent(oneFingerOrigin.x,oneFingerOrigin.y);
case MotionEvent.ACTION_MOVE:
float distance = sqrDistance(event);
float result = distance-distanceOrigin;
distanceOrigin=distance;
if(result>1||result<-1){
oneFingerOrigin.y=oneFingerOrigin.y+result;
osgNativeLib.mouseMoveEvent(oneFingerOrigin.x,oneFingerOrigin.y);
}
break;
case MotionEvent.ACTION_POINTER_UP:
mode =moveTypes.NONE;
osgNativeLib.mouseButtonReleaseEvent(oneFingerOrigin.x,oneFingerOrigin.y, 3);
break;
case MotionEvent.ACTION_UP:
mode =moveTypes.NONE;
osgNativeLib.mouseButtonReleaseEvent(oneFingerOrigin.x,oneFingerOrigin.y, 3);
break;
default :
Log.e(TAG,"2 point Action not captured");
}
break;
}
return true;
}
//Ui Listeners
OnClickListener uiListenerCenterView = new OnClickListener() {
public void onClick(View v) {
//Log.d(TAG, "Center View");
osgNativeLib.keyboardDown(32);
osgNativeLib.keyboardUp(32);
}
};
OnClickListener uiListenerChangeNavigation = new OnClickListener() {
public void onClick(View v) {
//Log.d(TAG, "Change Navigation");
if(navMode==navType.PRINCIPAL){
msgUiNavSecondary.show();
navMode=navType.SECONDARY;
}
else{
msgUiNavPrincipal.show();
navMode=navType.PRINCIPAL;
}
}
};
OnClickListener uiListenerChangeLight = new OnClickListener() {
public void onClick(View v) {
//Log.d(TAG, "Change Light");
if(lightMode==lightType.ON){
msgUiLightOff.show();
lightMode=lightType.OFF;
osgNativeLib.keyboardDown(108);
osgNativeLib.keyboardUp(108);
}
else{
msgUiLightOn.show();
lightMode=lightType.ON;
osgNativeLib.keyboardDown(108);
osgNativeLib.keyboardUp(108);
}
}
};
//Menu
@Override
public void colorChange(int color) {
// TODO Auto-generated method stub
// Do nothing
int red = Color.red(color);
int green = Color.green(color);
int blue = Color.blue(color);
//Log.d(TAG,"BACK color "+red+" "+green+" "+blue+" ");
osgNativeLib.setClearColor(red,green,blue);
}
//Android Life Cycle Menu
@Override
public boolean onCreateOptionsMenu(Menu menu) {
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.appmenu, menu);
return super.onCreateOptionsMenu(menu);
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle item selection
switch (item.getItemId()) {
case R.id.menuLoadObject:
Log.d(TAG,"Load Object");
loadLayerAddress.show();
return true;
case R.id.menuCleanScene:
Log.d(TAG,"Clean Scene");
osgNativeLib.clearContents();
return true;
case R.id.menuDeleteObject:
Log.d(TAG,"Delete a object");
String vNames[] = osgNativeLib.getObjectNames();
//Remove Layer Dialog
AlertDialog.Builder removeLayerDialogBuilder = new AlertDialog.Builder(this);
removeLayerDialogBuilder.setTitle(R.string.uiDialogTextChoseRemove);
removeLayerDialogBuilder.setItems(vNames, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int witch) {
// TODO Auto-generated method stub
osgNativeLib.unLoadObject(witch);
}
});
removeLayerDialog = removeLayerDialogBuilder.create();
if(vNames.length > 0)
removeLayerDialog.show();
return true;
case R.id.menuChangeBackground:
Log.d(TAG,"Change background color");
int[] test = new int [3];
test = osgNativeLib.getClearColor();
backgroundColor = Color.rgb(test[0], test[1], test[2]);
ColorPickerDialog colorDialog;
new ColorPickerDialog(this, this, backgroundColor).show();
return true;
case R.id.menuShowKeyboard:
Log.d(TAG,"Keyboard");
InputMethodManager mgr= (InputMethodManager)this.getSystemService(Context.INPUT_METHOD_SERVICE);
mgr.toggleSoftInput(InputMethodManager.SHOW_IMPLICIT, 0);
return true;
default:
return super.onOptionsItemSelected(item);
}
}
//Utilities
/** Show an event in the LogCat view, for debugging */
private void dumpEvent(MotionEvent event) {
String names[] = { "DOWN", "UP", "MOVE", "CANCEL", "OUTSIDE",
"POINTER_DOWN", "POINTER_UP", "7?", "8?", "9?" };
StringBuilder sb = new StringBuilder();
int action = event.getAction();
int actionCode = action & MotionEvent.ACTION_MASK;
sb.append("event ACTION_").append(names[actionCode]);
if (actionCode == MotionEvent.ACTION_POINTER_DOWN
|| actionCode == MotionEvent.ACTION_POINTER_UP) {
sb.append("(pid ").append(
action >> MotionEvent.ACTION_POINTER_ID_SHIFT);
sb.append(")");
}
sb.append("[");
for (int i = 0; i < event.getPointerCount(); i++) {
sb.append("#").append(i);
sb.append("(pid ").append(event.getPointerId(i));
sb.append(")=").append((int) event.getX(i));
sb.append(",").append((int) event.getY(i));
if (i + 1 < event.getPointerCount())
sb.append(";");
}
sb.append("]");
//Log.d(TAG, sb.toString());
}
private float sqrDistance(MotionEvent event) {
float x = event.getX(0) - event.getX(1);
float y = event.getY(0) - event.getY(1);
return (float)(Math.sqrt(x * x + y * y));
}
}

View File

@ -339,6 +339,8 @@ OSG_INIT_SINGLETON_PROXY(GLExtensionDisableStringInitializationProxy, osg::getGL
static void *handle = dlopen("libGLESv1_CM.so", RTLD_NOW);
#elif defined(OSG_GLES2_AVAILABLE)
static void *handle = dlopen("libGLESv2.so", RTLD_NOW);
#elif defined(OSG_GLES3_AVAILABLE)
static void *handle = dlopen("libGLESv3.so", RTLD_NOW);
#elif defined(OSG_GL1_AVAILABLE)
static void *handle = dlopen("libGL.so", RTLD_NOW);
#endif