VTK Android 3D地球
1.VTK Android 3D地球
通过 Android Java 层 通过JNI调用 VTK Android libs
https://github.com/panyingyun/vtkandroiddemo/blob/master/VTK3DEarth/app/src/main/cpp/main.cxx
/*
* Author: panyingyun(at)gmail.com
*
* Description: Demo(Earth) for Study VTK
*
*/
#include <jni.h>
#include <errno.h>
#include <sstream>
#include <vtkActor.h>
#include <vtkCellData.h>
#include <vtkColorTransferFunction.h>
#include <vtkDataArray.h>
#include <vtkInteractorStyleTrackballCamera.h>
#include <vtkJPEGReader.h>
#include <vtkNew.h>
#include <vtkPolyDataMapper.h>
#include <vtkRenderWindow.h>
#include <vtkRenderWindowInteractor.h>
#include <vtkRenderer.h>
#include <vtkSmartPointer.h>
#include <vtkSphereSource.h>
#include <vtkTexture.h>
#include <vtkCamera.h>
#include <vtkDebugLeaks.h>
#include <vtkGlyph3D.h>
#include <vtkPolyData.h>
#include <vtkPolyDataMapper.h>
#include <vtkRenderWindow.h>
#include <vtkRenderer.h>
#include <vtkSphereSource.h>
#include <vtkTextActor.h>
#include <vtkTextProperty.h>
#include <vtkAndroidRenderWindowInteractor.h>
#include <vtkCommand.h>
#include <android/log.h>
#define LOGI(...) ((void)__android_log_print(ANDROID_LOG_INFO, "NativeVTK", __VA_ARGS__))
#define LOGW(...) ((void)__android_log_print(ANDROID_LOG_WARN, "NativeVTK", __VA_ARGS__))
extern "C"
{
JNIEXPORT jlong JNICALL Java_com_kitware_JavaVTK_JavaVTKLib_init(JNIEnv *env, jobject obj, jint width, jint height);
JNIEXPORT void JNICALL Java_com_kitware_JavaVTK_JavaVTKLib_render(JNIEnv *env, jobject obj, jlong renWinP);
JNIEXPORT void JNICALL Java_com_kitware_JavaVTK_JavaVTKLib_onKeyEvent(JNIEnv *env, jobject obj, jlong udp,
jboolean down, jint keyCode, jint metaState, jint repeatCount);
JNIEXPORT void JNICALL Java_com_kitware_JavaVTK_JavaVTKLib_onMotionEvent(JNIEnv *env, jobject obj, jlong udp,
jint action,
jint eventPointer,
jint numPtrs,
jfloatArray xPos, jfloatArray yPos,
jintArray ids, jint metaState);
};
struct userData
{
vtkRenderWindow *RenderWindow;
vtkRenderer *Renderer;
vtkAndroidRenderWindowInteractor *Interactor;
};
// Example of updating text as we go
class vtkExampleCallback : public vtkCommand
{
public:
static vtkExampleCallback *New()
{
return new vtkExampleCallback;
}
virtual void Execute(vtkObject *caller, unsigned long, void *)
{
// Update cardinality of selection
double *pos = this->Camera->GetPosition();
std::ostringstream txt;
txt << "Camera positioned at: "
<< std::fixed
<< std::setprecision(2)
<< std::setw(6)
<< pos[0] << ", "
<< std::setw(6)
<< pos[1] << ", "
<< std::setw(6)
<< pos[2];
this->Text->SetInput(txt.str().c_str());
}
vtkExampleCallback()
{
this->Camera = 0;
this->Text = 0;
}
vtkCamera *Camera;
vtkTextActor *Text;
};
/*
* Here is where you would setup your pipeline and other normal VTK logic
*/
JNIEXPORT jlong JNICALL Java_com_kitware_JavaVTK_JavaVTKLib_init(JNIEnv *env, jobject obj, jint width, jint height)
{
vtkRenderWindow *renWin = vtkRenderWindow::New();
char jniS[4] = {'j', 'n', 'i', 0};
renWin->SetWindowInfo(jniS); // tell the system that jni owns the window not us
renWin->SetSize(width, height);
vtkNew<vtkRenderer> renderer;
renWin->AddRenderer(renderer.Get());
vtkNew<vtkAndroidRenderWindowInteractor> iren;
iren->SetRenderWindow(renWin);
// Create SphereSource
vtkNew<vtkSphereSource> source;
source->SetRadius(0.5);
source->SetPhiResolution(80);
source->SetThetaResolution(80);
// Create TextureMapToSphere
//vtkNew<vtkTextureMapToSphere> texturemap;
//texturemap->SetInputConnection(source->GetOutputPort());
// Create Texture
//vtkNew<vtkJPEGReader> jPEGReader;
//jPEGReader->SetFileName("/mnt/sdcard/earth.jpg");
//vtkNew<vtkTexture> texture;
//texture->SetInputConnection(jPEGReader->GetOutputPort());
// Create Data Set Mapper
vtkNew<vtkPolyDataMapper> mapper;
mapper->SetInputConnection(source->GetOutputPort());
// Create Actor
vtkNew<vtkActor> actor;
actor->SetMapper(mapper);
//actor->SetTexture(texture);
renderer->AddActor(actor.Get());
renderer->SetBackground(0.4, 0.5, 0.6);
vtkNew<vtkTextActor> ta;
ta->SetInput("Droids Rock");
ta->GetTextProperty()->SetColor(0.5, 1.0, 0.0);
ta->SetDisplayPosition(50, 50);
ta->GetTextProperty()->SetFontSize(32);
renderer->AddActor(ta.Get());
vtkNew<vtkExampleCallback> cb;
cb->Camera = renderer->GetActiveCamera();
cb->Text = ta.Get();
iren->AddObserver(vtkCommand::InteractionEvent, cb.Get());
struct userData *foo = new struct userData();
foo->RenderWindow = renWin;
foo->Renderer = renderer.Get();
foo->Interactor = iren.Get();
return (jlong)foo;
}
JNIEXPORT void JNICALL Java_com_kitware_JavaVTK_JavaVTKLib_render(JNIEnv *env, jobject obj, jlong udp)
{
struct userData *foo = (userData *)(udp);
foo->RenderWindow->SwapBuffersOff(); // android does it
foo->RenderWindow->Render();
foo->RenderWindow->SwapBuffersOn(); // reset
}
JNIEXPORT void JNICALL Java_com_kitware_JavaVTK_JavaVTKLib_onKeyEvent(JNIEnv *env, jobject obj, jlong udp,
jboolean down, jint keyCode, jint metaState, jint repeatCount)
{
struct userData *foo = (userData *)(udp);
foo->Interactor->HandleKeyEvent(down, keyCode, metaState, repeatCount);
}
JNIEXPORT void JNICALL Java_com_kitware_JavaVTK_JavaVTKLib_onMotionEvent(JNIEnv *env, jobject obj, jlong udp,
jint action,
jint eventPointer,
jint numPtrs,
jfloatArray xPos, jfloatArray yPos,
jintArray ids, jint metaState)
{
struct userData *foo = (userData *)(udp);
int xPtr[VTKI_MAX_POINTERS];
int yPtr[VTKI_MAX_POINTERS];
int idPtr[VTKI_MAX_POINTERS];
// only allow VTKI_MAX_POINTERS touches right now
if (numPtrs > VTKI_MAX_POINTERS)
{
numPtrs = VTKI_MAX_POINTERS;
}
// fill in the arrays
jfloat *xJPtr = env->GetFloatArrayElements(xPos, 0);
jfloat *yJPtr = env->GetFloatArrayElements(yPos, 0);
jint *idJPtr = env->GetIntArrayElements(ids, 0);
for (int i = 0; i < numPtrs; ++i)
{
xPtr[i] = (int)xJPtr[i];
yPtr[i] = (int)yJPtr[i];
idPtr[i] = idJPtr[i];
}
env->ReleaseIntArrayElements(ids, idJPtr, 0);
env->ReleaseFloatArrayElements(xPos, xJPtr, 0);
env->ReleaseFloatArrayElements(yPos, yJPtr, 0);
foo->Interactor->HandleMotionEvent(action, eventPointer, numPtrs, xPtr, yPtr, idPtr, metaState);
}
遇到 vtkTextureMapToSphere 找不到的情况,地球纹理贴图暂时不行了,暂时未能有时间去解决。先体验这个过程吧