Files
face_sdk/app/src/main/cpp/main.cpp
T
2025-10-26 00:13:08 +08:00

140 lines
4.8 KiB
C++

#include <jni.h>
#include <game-activity/native_app_glue/android_native_app_glue.h>
#include <game-activity/GameActivity.h>
#include "AndroidOut.h"
#include "FaceApp.h"
#include <android/asset_manager.h>
#include <chrono>
#include <thread>
using namespace std;
extern "C" {
android_app* g_android_app = nullptr;
Application* g_Application = nullptr;
AAssetManager* g_assetManager = nullptr;
void handle_cmd(android_app *pApp, int32_t cmd) {
switch (cmd) {
case APP_CMD_INIT_WINDOW:
aout << "APP_CMD_INIT_WINDOW" << std::endl;
g_Application->initVulkan();
break;
case APP_CMD_TERM_WINDOW:
aout << "APP_CMD_TERM_WINDOW" << std::endl;
break;
default:
break;
}
}
const int ArgLen = 128*1024;
char g_InitArgString[ArgLen] = {0};
void android_main(struct android_app *pApp) {
aout << "Welcome to android_main" << std::endl;
g_android_app = pApp;
g_assetManager = pApp->activity->assetManager;
FaceApp application;
g_Application = &application;
application.SetInitArg(g_InitArgString);
pApp->onAppCmd = handle_cmd;
android_app_set_motion_event_filter(pApp, nullptr);
do {
auto ms = chrono::duration_cast<chrono::milliseconds>(chrono::system_clock::now().time_since_epoch()).count();
// Process all pending events before running game logic.
bool done = false;
while (!done) {
int timeout = 0;
int events;
android_poll_source *pSource;
int result = ALooper_pollOnce(timeout, nullptr, &events, reinterpret_cast<void**>(&pSource));
switch (result) {
case ALOOPER_POLL_TIMEOUT:
[[clang::fallthrough]];
case ALOOPER_POLL_WAKE:
// No events occurred before the timeout or explicit wake. Stop checking for events.
done = true;
break;
case ALOOPER_EVENT_ERROR:
aout << "ALooper_pollOnce returned an error" << std::endl;
break;
case ALOOPER_POLL_CALLBACK:
break;
default:
if (pSource) {
pSource->process(pApp, pSource);
}
}
}
if(application.isInited())
{
application.drawFrame();
}
auto end_ms = chrono::duration_cast<chrono::milliseconds>(chrono::system_clock::now().time_since_epoch()).count();
this_thread::sleep_for(chrono::milliseconds((end_ms-ms)));
} while (!pApp->destroyRequested);
application.cleanup();
}
}
extern void TextureLoadProcessWithVulkan(uint8_t* data, int width, int height, int rowStride, size_t dataSize);
extern void ReceiveFacePoint(float* pos, int count, int width, int height);
void processWithVulkan(uint8_t* data, int width, int height, int format,
int rowStride, size_t dataSize) {
TextureLoadProcessWithVulkan(data, width, height, rowStride, dataSize);
}
extern "C"
JNIEXPORT void JNICALL
Java_com_hmwl_face_1sdk_FaceActivity_processImageNative(JNIEnv *env, jobject thiz, jobject buffer,
jint width, jint height, jint format,
jint row_stride, jint pixel_stride,
jint rotation) {
// TODO: implement processImageNative()
uint8_t* imageData = static_cast<uint8_t*>(env->GetDirectBufferAddress(buffer));
jlong capacity = env->GetDirectBufferCapacity(buffer);
if (imageData == nullptr) {
return;
}
// 在这里将图像数据传递给 Vulkan
// 创建 Vulkan 图像或更新现有图像
processWithVulkan(imageData, width, height, format, row_stride, capacity);
}
extern "C"
JNIEXPORT void JNICALL
Java_com_hmwl_face_1sdk_FaceActivity_passDataToNative(JNIEnv *env, jobject thiz, jobject buffer,
jint point_count, jint width, jint height) {
// TODO: implement passDataToNative()
float* pos = static_cast<float*>(env->GetDirectBufferAddress(buffer));
if (pos == nullptr) {
// 处理错误
return;
}
// 或者直接将指针传递给Vulkan
ReceiveFacePoint(pos, point_count, width, height);
}
extern "C"
JNIEXPORT void JNICALL
Java_com_hmwl_face_1sdk_FaceActivity_SetCppInitArg(JNIEnv *env, jobject thiz, jstring json) {
// TODO: implement SetCppInitArg()
const char *nativeString = env->GetStringUTFChars(json, nullptr);
jsize len = env->GetStringUTFLength(json);
if(len > ArgLen)
{
aout << "ArgLen to long:" << len << std::endl;
return;
}
memcpy(g_InitArgString, nativeString, len);
}