#include "NativeRenderThread.h" #include "NativeEGLOCCT/common.h" #include #include #include namespace NativeOpenCAX { NativeRenderThread::NativeRenderThread() : isRunning_(false), nativeWindow_(nullptr), windowWidth_(1280), windowHeight_(720) { eglCore_ = new EGLCore(); } NativeRenderThread::~NativeRenderThread() { stop(); } bool NativeRenderThread::start(OHNativeWindow* window) { if (isRunning_) { return true; } nativeWindow_ = window; 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() { // 初始化EGL if (!eglCore_->init(nativeWindow_)) { OH_LOG_Print(LOG_APP, LOG_ERROR, LOG_PRINT_DOMAIN, "EGLCoreInit","Failed to initialize EGL"); } // 初始化OCCT渲染器 if (!renderer_.init(windowWidth_, windowHeight_,eglCore_)) { OH_LOG_Print(LOG_APP, LOG_ERROR, LOG_PRINT_DOMAIN, "NativeRenderInit","Failed to initialize OCCT renderer"); eglCore_->destroy(); } 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_VIEW_FRONT: renderer_.SetFrontView(); break; case CMD_VIEW_TOP: renderer_.SetFrontView(); break; case CMD_VIEW_LEFT_SIDE: renderer_.SetFrontView(); break; case CMD_VIEW_RIGHT_SIDE: renderer_.SetFrontView(); break; case CMD_VIEW_BOTTOM: renderer_.SetFrontView(); break; case CMD_VIEW_REAR: renderer_.SetFrontView(); break; case CMD_VIEW_ISO: renderer_.SetFrontView(); break; case CMD_VIEW_DIM: renderer_.SetFrontView(); break; case CMD_EXIT: isRunning_ = false; break; } } if (!isRunning_) { break; } // 渲染 eglCore_->makeCurrent(); renderer_.render(); eglCore_->swapBuffers(); // 调用渲染完成回调 Callback callback; { std::lock_guard lock(callbackMutex_); callback = renderCompleteCallback_; } if (callback) { callback(); } // 控制帧率 usleep(8333); // ~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::swicthView(std::string strView) { std::lock_guard lock(commandMutex_); CommandType cmdType; if(strView=="CMD_VIEW_FRONT"){ cmdType=CMD_VIEW_FRONT; } if(strView=="CMD_VIEW_TOP"){ cmdType=CMD_VIEW_TOP; } if(strView=="CMD_VIEW_LEFT_SIDE"){ cmdType=CMD_VIEW_LEFT_SIDE; } if(strView=="CMD_VIEW_RIGHT_SIDE"){ cmdType=CMD_VIEW_RIGHT_SIDE; } if(strView=="CMD_VIEW_BOTTOM"){ cmdType=CMD_VIEW_BOTTOM; } if(strView=="CMD_VIEW_REAR"){ cmdType=CMD_VIEW_REAR; } if(strView=="CMD_VIEW_ISO"){ cmdType=CMD_VIEW_ISO; } if(strView=="CMD_VIEW_DIM"){ cmdType=CMD_VIEW_DIM; } commandQueue_.push(RenderCommand(cmdType)); 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