OpenCAX/entry/src/main/cpp/NativeEGLOCCT/NativeRenderThread.cpp
JackLee 6a4e702dbd 增加视图切换功能,但是需要归一化操作.
目前只是实现了功能.需要对初始世界坐标进行标定
2026-03-22 22:38:16 +08:00

238 lines
7.0 KiB
C++

#include "NativeRenderThread.h"
#include "NativeEGLOCCT/common.h"
#include <cstdio>
#include <unistd.h>
#include <hilog/log.h>
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<std::mutex> 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<std::mutex> 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<int>(command.param2);
windowHeight_ = static_cast<int>(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<std::mutex> lock(callbackMutex_);
callback = renderCompleteCallback_;
}
if (callback) {
callback();
}
// 控制帧率
usleep(8333); // ~60 FPS
}
}
void NativeRenderThread::loadModel(const std::string& filePath) {
std::lock_guard<std::mutex> 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<std::mutex> 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<std::mutex> 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<std::mutex> lock(commandMutex_);
commandQueue_.push(RenderCommand(CMD_RESET_VIEW));
commandCondition_.notify_one();
}
void NativeRenderThread::swicthView(std::string strView) {
std::lock_guard<std::mutex> 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<std::mutex> 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<std::mutex> lock(commandMutex_);
RenderCommand cmd(CMD_RESIZE);
cmd.param2 = static_cast<float>(width);
cmd.param3 = static_cast<float>(height);
commandQueue_.push(cmd);
commandCondition_.notify_one();
}
void NativeRenderThread::registerRenderCompleteCallback(Callback callback) {
std::lock_guard<std::mutex> lock(callbackMutex_);
renderCompleteCallback_ = callback;
}
} // namespace OCCTRenderer