From Jorge Ciges, "two clean example viewers (GLES1/2) that permit load models withouth recompiling by options in the menu and some basic options. basic options.
As Rafa and I told you earlier this can't be integrated in the CMAKE chain. It needs to be compiled by the user out of the OSG standard compilation. It could be stored in the examples. That way users will not come here asking for the examples. Main characteristics are: -Menu with loading and unloading by path. -Return to home view -Keyboard capabilities with manipilator switch and basic state changing. -Change color screen. -Osg log bypassed to LogCat (This comes practically straight from Marcin Hajder example I've only added personal TAG) -Earmbi / Earmbi V7 -Install to SD (if the device supports the feature) And that's all. Now I'm looking to fix the environmental mapping with true GLES (it does not work well in Android) I will try to make it in time for 3.0. The other work that i'm studying Dynamic build with Android but that will need a lot of time to test.
21
examples/osgAndroidExampleGLES1/AndroidManifest.xml
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
<?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="8" android:minSdkVersion="8"></uses-sdk>
|
||||||
|
<uses-feature android:glEsVersion="0x00010001"/> <!-- OpenGL min requierements (1.1) -->
|
||||||
|
<uses-permission android:name="android.permission.INTERNET"/>
|
||||||
|
|
||||||
|
<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>
|
11
examples/osgAndroidExampleGLES1/default.properties
Normal 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
|
67
examples/osgAndroidExampleGLES1/jni/Android.mk
Normal 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 -lGLESv1_CM -ldl -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)
|
11
examples/osgAndroidExampleGLES1/jni/Application.mk
Normal 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-7
|
||||||
|
APP_STL := gnustl_static
|
||||||
|
APP_CPPFLAGS := -fexceptions -frtti
|
||||||
|
APP_ABI := armeabi armeabi-v7a
|
||||||
|
APP_MODULES := osgNativeLib
|
@ -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;
|
||||||
|
}
|
||||||
|
}
|
@ -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_ */
|
205
examples/osgAndroidExampleGLES1/jni/OsgMainApp.cpp
Normal file
@ -0,0 +1,205 @@
|
|||||||
|
#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::readNodeFile(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);
|
||||||
|
_root->addChild(loadedModel);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
_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);
|
||||||
|
|
||||||
|
_root = new osg::Group();
|
||||||
|
|
||||||
|
_viewer->realize();
|
||||||
|
|
||||||
|
_state = _root->getOrCreateStateSet();
|
||||||
|
_state->setMode(GL_LIGHTING, osg::StateAttribute::ON);
|
||||||
|
_state->setMode(GL_DEPTH_TEST, osg::StateAttribute::ON);
|
||||||
|
_state->setMode(GL_CULL_FACE, osg::StateAttribute::ON);
|
||||||
|
|
||||||
|
_viewer->setSceneData(_root.get());
|
||||||
|
|
||||||
|
_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();
|
||||||
|
}
|
138
examples/osgAndroidExampleGLES1/jni/OsgMainApp.hpp
Normal file
@ -0,0 +1,138 @@
|
|||||||
|
/*
|
||||||
|
* 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;
|
||||||
|
};
|
||||||
|
|
||||||
|
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_ */
|
113
examples/osgAndroidExampleGLES1/jni/osgNativeLib.cpp
Normal 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, 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, false);
|
||||||
|
const char *nativeName = env->GetStringUTFChars(name, 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;
|
||||||
|
}
|
36
examples/osgAndroidExampleGLES1/proguard.cfg
Normal 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 *;
|
||||||
|
}
|
BIN
examples/osgAndroidExampleGLES1/res/drawable-hdpi/osg.png
Normal file
After Width: | Height: | Size: 12 KiB |
After Width: | Height: | Size: 4.6 KiB |
BIN
examples/osgAndroidExampleGLES1/res/drawable-ldpi/osg.png
Normal file
After Width: | Height: | Size: 5.8 KiB |
BIN
examples/osgAndroidExampleGLES1/res/drawable-mdpi/osg.png
Normal file
After Width: | Height: | Size: 7.5 KiB |
@ -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>
|
12
examples/osgAndroidExampleGLES1/res/layout/main.xml
Normal 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>
|
@ -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>
|
9
examples/osgAndroidExampleGLES1/res/menu/appmenu.xml
Normal 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>
|
28
examples/osgAndroidExampleGLES1/res/values/strings.xml
Normal 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>
|
@ -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));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -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 1.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 1 context");
|
||||||
|
checkEglError("Before eglCreateContext", egl);
|
||||||
|
int[] attrib_list = {EGL_CONTEXT_CLIENT_VERSION, 1, 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 = 1;
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -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();
|
||||||
|
|
||||||
|
}
|
@ -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));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
21
examples/osgAndroidExampleGLES2/AndroidManifest.xml
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
<?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="8" android:minSdkVersion="8"></uses-sdk>
|
||||||
|
<uses-feature android:glEsVersion="0x00020000"/> <!-- OpenGL min requierements (2.0) -->
|
||||||
|
<uses-permission android:name="android.permission.INTERNET"/>
|
||||||
|
|
||||||
|
<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>
|
11
examples/osgAndroidExampleGLES2/default.properties
Normal 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
|
67
examples/osgAndroidExampleGLES2/jni/Android.mk
Normal 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 -lGLESv2 -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)
|
11
examples/osgAndroidExampleGLES2/jni/Application.mk
Normal 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-7
|
||||||
|
APP_STL := gnustl_static
|
||||||
|
APP_CPPFLAGS := -fexceptions -frtti
|
||||||
|
APP_ABI := armeabi armeabi-v7a
|
||||||
|
APP_MODULES := osgNativeLib
|
@ -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;
|
||||||
|
}
|
||||||
|
}
|
@ -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_ */
|
217
examples/osgAndroidExampleGLES2/jni/OsgMainApp.cpp
Normal 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::readNodeFile(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();
|
||||||
|
}
|
182
examples/osgAndroidExampleGLES2/jni/OsgMainApp.hpp
Normal 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_ */
|
113
examples/osgAndroidExampleGLES2/jni/osgNativeLib.cpp
Normal 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, 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, false);
|
||||||
|
const char *nativeName = env->GetStringUTFChars(name, 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;
|
||||||
|
}
|
36
examples/osgAndroidExampleGLES2/proguard.cfg
Normal 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 *;
|
||||||
|
}
|
BIN
examples/osgAndroidExampleGLES2/res/drawable-hdpi/osg.png
Normal file
After Width: | Height: | Size: 12 KiB |
After Width: | Height: | Size: 4.6 KiB |
BIN
examples/osgAndroidExampleGLES2/res/drawable-ldpi/osg.png
Normal file
After Width: | Height: | Size: 5.8 KiB |
BIN
examples/osgAndroidExampleGLES2/res/drawable-mdpi/osg.png
Normal file
After Width: | Height: | Size: 7.5 KiB |
@ -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>
|
12
examples/osgAndroidExampleGLES2/res/layout/main.xml
Normal 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>
|
@ -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>
|
9
examples/osgAndroidExampleGLES2/res/menu/appmenu.xml
Normal 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>
|
28
examples/osgAndroidExampleGLES2/res/values/strings.xml
Normal 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>
|
@ -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));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -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();
|
||||||
|
|
||||||
|
}
|
@ -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));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|