#include "NativeRenderThread.h" #include "NativeEGLOCCT/common.h" #include #include #include namespace NativeOpenCAX { NativeRenderThread::NativeRenderThread() : isRunning_(false), nativeWindow_(nullptr), windowWidth_(1280), windowHeight_(720) {} NativeRenderThread::~NativeRenderThread() { stop(); } bool NativeRenderThread::start(OHNativeWindow* window) { if (isRunning_) { return true; } nativeWindow_ = window; // 初始化EGL if (!eglCore_.init(nativeWindow_)) { printf("Failed to initialize EGL\n"); return false; } // 初始化OCCT渲染器 if (!renderer_.init(nativeWindow_,windowWidth_, windowHeight_)) { printf("Failed to initialize OCCT renderer\n"); eglCore_.destroy(); return false; } isRunning_ = true; renderThread_ = std::thread(&NativeRenderThread::renderLoop, this); return true; } void NativeRenderThread::stop() { if (!isRunning_) { return; } isRunning_ = false; { std::lock_guard lock(commandMutex_); commandQueue_.push(RenderCommand(CMD_EXIT)); } commandCondition_.notify_one(); if (renderThread_.joinable()) { renderThread_.join(); } eglCore_.destroy(); } void NativeRenderThread::renderLoop() { while (isRunning_) { RenderCommand command; bool hasCommand = false; { std::unique_lock lock(commandMutex_); commandCondition_.wait_for(lock, std::chrono::milliseconds(16), [this] { return !commandQueue_.empty(); }); if (!commandQueue_.empty()) { command = commandQueue_.front(); commandQueue_.pop(); hasCommand = true; } } if (hasCommand) { switch (command.type) { case CMD_LOAD_MODEL: renderer_.loadModel(command.param1); break; case CMD_SET_ROTATION: renderer_.setRotation(command.param2, command.param3); break; case CMD_SET_TRANSLATION: renderer_.setTranslation(command.param2, command.param3); break; case CMD_RESET_VIEW: renderer_.resetView(); break; case CMD_SET_CLEAR_COLOR: renderer_.setClearColor(command.param2, command.param3, command.param4, command.param5); break; case CMD_RESIZE: windowWidth_ = static_cast(command.param2); windowHeight_ = static_cast(command.param3); renderer_.resize(windowWidth_, windowHeight_); break; case CMD_EXIT: isRunning_ = false; break; } } if (!isRunning_) { break; } // 渲染 eglCore_.makeCurrent(); renderer_.render(); eglCore_.swapBuffers(); OH_LOG_Print(LOG_APP, LOG_ERROR, LOG_PRINT_DOMAIN, "NativeRenderThead", "NativeRenderThead Done"); // 调用渲染完成回调 Callback callback; { std::lock_guard lock(callbackMutex_); callback = renderCompleteCallback_; } if (callback) { callback(); } // 控制帧率 usleep(16000); // ~60 FPS } } void NativeRenderThread::loadModel(const std::string& filePath) { std::lock_guard lock(commandMutex_); RenderCommand cmd(CMD_LOAD_MODEL); cmd.param1 = filePath; commandQueue_.push(cmd); commandCondition_.notify_one(); } void NativeRenderThread::setRotation(float xAngle, float yAngle) { std::lock_guard lock(commandMutex_); RenderCommand cmd(CMD_SET_ROTATION); cmd.param2 = xAngle; cmd.param3 = yAngle; commandQueue_.push(cmd); commandCondition_.notify_one(); } void NativeRenderThread::setTranslation(float x, float y) { std::lock_guard lock(commandMutex_); RenderCommand cmd(CMD_SET_TRANSLATION); cmd.param2 = x; cmd.param3 = y; commandQueue_.push(cmd); commandCondition_.notify_one(); } void NativeRenderThread::resetView() { std::lock_guard lock(commandMutex_); commandQueue_.push(RenderCommand(CMD_RESET_VIEW)); commandCondition_.notify_one(); } void NativeRenderThread::setClearColor(float r, float g, float b, float a) { std::lock_guard lock(commandMutex_); RenderCommand cmd(CMD_SET_CLEAR_COLOR); cmd.param2 = r; cmd.param3 = g; cmd.param4 = b; cmd.param5 = a; commandQueue_.push(cmd); commandCondition_.notify_one(); } void NativeRenderThread::resizeWindow(int width, int height) { std::lock_guard lock(commandMutex_); RenderCommand cmd(CMD_RESIZE); cmd.param2 = static_cast(width); cmd.param3 = static_cast(height); commandQueue_.push(cmd); commandCondition_.notify_one(); } void NativeRenderThread::registerRenderCompleteCallback(Callback callback) { std::lock_guard lock(callbackMutex_); renderCompleteCallback_ = callback; } } // namespace OCCTRenderer