190 lines
5.4 KiB
C++
190 lines
5.4 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) {}
|
|
|
|
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<std::mutex> 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<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_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<std::mutex> lock(callbackMutex_);
|
|
callback = renderCompleteCallback_;
|
|
}
|
|
|
|
if (callback) {
|
|
callback();
|
|
}
|
|
|
|
// 控制帧率
|
|
usleep(16000); // ~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::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
|