Hello everyone,
This project is implemented based on NativeVTK and vtkAndroidRenderWindowInteractor, which worked in vtk 9.3.1 (there may be a crash on the first run), but I compiled the latest code from gitlab and it crashes when vtkRenderWindow::Render();I want to use vtkContext2D, but it crashes on android devices. There are a lot of questions this time, and I hope you will give me a little hint.
My work:
The first thing you need to do is create a project “Game Activity C++” ;
Next configure the cmakelists.txt
cmake_minimum_required(VERSION 3.22.1)
project("test")
set(VTK_DIR "vtk-android/lib/cmake/vtk-9.3")
find_package(VTK REQUIRED)
include_directories(${CMAKE_CURRENT_SOURCE_DIR})
add_library(test SHARED
main.cpp
)
find_package(game-activity REQUIRED CONFIG)
target_link_libraries(test
game-activity::game-activity
${VTK_LIBRARIES}
EGL
GLESv3
android
log)
vtk_module_autoinit(
TARGETS ${CMAKE_PROJECT_NAME}
MODULES ${VTK_LIBRARIES}
)
main.cpp
#include <jni.h>
#include <game-activity/GameActivity.cpp>
#include <game-text-input/gametextinput.cpp>
#include <game-activity/native_app_glue/android_native_app_glue.c>
#include "render/Renderer.h"
extern "C"
{
void handle_cmd(android_app *app, int32_t cmd)
{
switch (cmd)
{
case APP_CMD_INIT_WINDOW:
Renderer::GetInstance().SetAndroidApplication(app);
break;
case APP_CMD_TERM_WINDOW:
Renderer::GetInstance().Terminate();
break;
case APP_CMD_WINDOW_REDRAW_NEEDED://redraw
Renderer::GetInstance().Render();
break;
default:
break;
}
}
bool motion_event_filter_func(const GameActivityMotionEvent *motionEvent)
{
auto sourceClass = motionEvent->source & AINPUT_SOURCE_CLASS_MASK;
return (sourceClass == AINPUT_SOURCE_CLASS_POINTER ||
sourceClass == AINPUT_SOURCE_CLASS_JOYSTICK);
}
void android_main(struct android_app *app)
{
app->onAppCmd = handle_cmd;
android_app_set_motion_event_filter(app, motion_event_filter_func);
Renderer& renderer = Renderer::GetInstance();
int events;
android_poll_source *pSource;
while (!app->destroyRequested)
{
if (ALooper_pollOnce(0, nullptr, &events, (void **)&pSource) >= 0)
{
if (pSource)
{
pSource->process(app, pSource);
}
if(app->destroyRequested){
renderer.Terminate();
}
}
renderer.Render();
}
}
}
Renderer.h
//
// Created by Roque on 2024/9/22.
//
#include <vtkRenderer.h>
#include <vtkRenderWindow.h>
#include <vtkRenderWindowInteractor.h>
#include <game-activity/native_app_glue/android_native_app_glue.h>
class Renderer {
private:
vtkRenderer *renderer2D{nullptr};
vtkRenderer *renderer3D{nullptr};
vtkRenderWindow *renderWindow{nullptr};
vtkRenderWindowInteractor *interactor{nullptr};
android_app *app{nullptr};
std::atomic_bool enbleRender{false};
private:
Renderer();
~Renderer();
Renderer(const Renderer &) = delete;
Renderer &operator=(const Renderer &) = delete;
public:
static Renderer &GetInstance();
bool Enable() { return this->enbleRender; }
void SetAndroidApplication(android_app *app);
void Init();
void SetRenderer2D(vtkRenderer *renderer);
void SetRenderer3D(vtkRenderer *renderer);
void Render();
void Terminate();
vtkRenderWindow *GetRenderWindow();
};
Renderer.cpp
Renderer::Renderer()
{
renderWindow = vtkRenderWindow::New();
interactor = vtkRenderWindowInteractor::New();
renderWindow->SetInteractor(interactor);
interactor->Disable();
}
Renderer::~Renderer()
{
renderWindow->Delete();
interactor->Delete();
}
Renderer& Renderer::GetInstance()
{
static Renderer instance;
return instance;
}
void Renderer::SetAndroidApplication(android_app* app)
{
if(app==nullptr||app->window==nullptr) return;
this->app = app;
renderWindow->SetWindowId(app->window);
renderWindow->Render();//**there may be a crash**
DeviceScreen& screen = DeviceScreen::GetInstance();
int*size = renderWindow->GetSize();
if(size) screen.SetSize(size);
Init();
}
void Renderer::Init(){
if(renderer2D==nullptr){
SetRenderer2D(SceneManager::GetInstance().GetRenderer2D());
}
if(renderer3D==nullptr){
SetRenderer3D(SceneManager::GetInstance().GetRenderer3D());
}
renderWindow->SetNumberOfLayers(2);
renderWindow->AddRenderer(renderer3D);
renderWindow->AddRenderer(renderer2D);
renderWindow->SetMultiSamples(8); // hardware smooth
this->enbleRender = true;
}
void Renderer::SetRenderer2D(vtkRenderer* renderer){
this->renderer2D = renderer;
}
void Renderer::SetRenderer3D(vtkRenderer* renderer){
this->renderer3D = renderer;
}
void Renderer::Render()
{
if(enbleRender){
SceneManager& manager = SceneManager::GetInstance();
manager.EventProcess(app);
manager.Execute();
renderWindow->Render();
}
}
void Renderer::Terminate(){
this->enbleRender = false;
renderWindow->Finalize();
}
vtkRenderWindow* Renderer::GetRenderWindow()
{
return this->renderWindow;
}