233 lines
8.1 KiB
C++
233 lines
8.1 KiB
C++
#include "RenderThread.h"
|
||
#include "Font_FontAspect.hxx"
|
||
#include "NativeEGLOCCT/common.h"
|
||
#include <cstdio>
|
||
#include <unistd.h>
|
||
#include <hilog/log.h>
|
||
namespace NativeNXEA {
|
||
|
||
RenderThread::RenderThread()
|
||
: isRunning_(false)
|
||
{
|
||
|
||
}
|
||
|
||
RenderThread::~RenderThread() {
|
||
stop();
|
||
}
|
||
void RenderThread::InitRender(ThreadInfo _thrInfo){
|
||
OH_LOG_Print(LOG_APP, LOG_ERROR, LOG_PRINT_DOMAIN, "renderLoop","Thread ID: %{public}d",std::this_thread::get_id());
|
||
thrInfo=_thrInfo;
|
||
}
|
||
|
||
bool RenderThread::start() {
|
||
if (isRunning_) {
|
||
return true;
|
||
}
|
||
|
||
isRunning_ = true;
|
||
|
||
rdThread = std::thread(&RenderThread::renderLoop, this);
|
||
return true;
|
||
}
|
||
|
||
void RenderThread::stop() {
|
||
if (!isRunning_) {
|
||
return;
|
||
}
|
||
|
||
isRunning_ = false;
|
||
|
||
{
|
||
std::lock_guard<std::mutex> lock(commandMutex_);
|
||
commandQueue_.push(RenderCommand(CMD_EXIT));
|
||
}
|
||
commandCondition_.notify_one();
|
||
|
||
if (rdThread.joinable()) {
|
||
rdThread.join();
|
||
}
|
||
eglSubCore->destroy(thrInfo.eglCore->GetEGLDisplay());
|
||
}
|
||
void RenderThread::initFontMgr(){
|
||
ftMgr=Font_FontMgr::GetInstance();
|
||
ftMgr->InitFontDataBase();
|
||
ftMgr->SetPrintErrors(true);
|
||
ftMgr->SetTraceAliases(true);
|
||
Handle(Font_SystemFont) sysFont=new Font_SystemFont("HarmonyOS_Sans_Medium");
|
||
sysFont->SetFontPath(Font_FontAspect_Regular, "/data/storage/el2/base/haps/entry/files/fonts/");
|
||
// 注册字体。第二个参数如果是 Standard_True,表示强制注册,即使同名也覆盖。
|
||
bool isRegistered = ftMgr->RegisterFont(sysFont, Standard_True);
|
||
|
||
if (!isRegistered) {
|
||
OH_LOG_Print(LOG_APP, LOG_INFO, LOG_DOMAIN, "OCCT","Error: Cannot register font: %{public}s",sysFont->FontName().ToCString());
|
||
return; // 或者进行错误处理
|
||
} else {
|
||
OH_LOG_Print(LOG_APP, LOG_INFO, LOG_DOMAIN, "OCCT","Successfully registered font: %{public}s",sysFont->FontName().ToCString());
|
||
}
|
||
|
||
Handle(Font_SystemFont) fsf;
|
||
fsf=ftMgr->GetFont("HarmonyOS_Sans_Medium");
|
||
OH_LOG_Print(LOG_APP, LOG_INFO, LOG_DOMAIN, "OCCT","OCCT Path: %{public}s", fsf->FontPath(Font_FontAspect_Regular).ToCString());
|
||
OH_LOG_Print(LOG_APP, LOG_INFO, LOG_DOMAIN, "OCCT","OCCT GetFont: %{public}s", fsf->FontName().ToCString());
|
||
//输出所有字体
|
||
NCollection_Sequence<occ::handle<TCollection_HAsciiString>> theAliases;
|
||
ftMgr->GetAllAliases(theAliases);
|
||
for(auto ft:theAliases){
|
||
OH_LOG_Print(LOG_APP, LOG_INFO, LOG_DOMAIN, "OCCT","OCCT Aliases: %{public}s", ft->ToCString());
|
||
}
|
||
//checkfont
|
||
NCollection_List<occ::handle<Font_SystemFont>> fsfs;
|
||
fsfs=ftMgr->GetAvailableFonts();
|
||
for(auto fta:fsfs){
|
||
OH_LOG_Print(LOG_APP, LOG_INFO, LOG_DOMAIN, "OCCT","OCCT Font: %{public}s", fta->FontName().ToCString());
|
||
OH_LOG_Print(LOG_APP, LOG_INFO, LOG_DOMAIN, "OCCT","OCCT Font Path: %{public}s", fta->FontPath(Font_FontAspect_Regular).ToCString());
|
||
}
|
||
}
|
||
void RenderThread::renderLoop() {
|
||
OH_LOG_Print(LOG_APP, LOG_ERROR, LOG_PRINT_DOMAIN, "renderLoop",
|
||
"Thread ID: %{public}s",
|
||
reinterpret_cast<std::ostringstream&>(std::ostringstream() << std::this_thread::get_id()).str().c_str());
|
||
//初始化OCCT字体管理
|
||
initFontMgr();
|
||
eglSubCore=new EGLSubCore();
|
||
eglSubCore->InitEGLSubCore(thrInfo.eglCore->GetEGLDisplay(), thrInfo.eglCore->GetEGLConfig(), thrInfo.win);
|
||
render=new Render(thrInfo.width,thrInfo.height);
|
||
if (render->init(thrInfo.eglCore->GetEGLDisplay(),eglSubCore->eglCtx,thrInfo.eglCore->GetEGLConfig())) {
|
||
OH_LOG_Print(LOG_APP, LOG_ERROR, LOG_PRINT_DOMAIN, "NativeRenderInit ","Render Init Done");
|
||
}else{
|
||
OH_LOG_Print(LOG_APP, LOG_ERROR, LOG_PRINT_DOMAIN, "NativeRenderInit","Render Init Failed");
|
||
eglSubCore->destroy(thrInfo.eglCore->GetEGLDisplay());
|
||
}
|
||
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:
|
||
render->loadModel(command.param1);
|
||
break;
|
||
case CMD_SET_ROTATION:
|
||
render->setRotation(command.param2, command.param3);
|
||
break;
|
||
case CMD_SET_TRANSLATION:
|
||
render->SetMoveTo(command.param2, command.param3);
|
||
break;
|
||
case CMD_RESET_VIEW:
|
||
render->resetView();
|
||
break;
|
||
case CMD_SET_CLEAR_COLOR:
|
||
render->setClearColor(command.param2, command.param3, command.param4, command.param5);
|
||
break;
|
||
case CMD_RESIZE:
|
||
rdWidth = static_cast<int>(command.param2);
|
||
rdHeight = static_cast<int>(command.param3);
|
||
render->resize(rdWidth, rdHeight);
|
||
break;
|
||
case CMD_SWITCH_VIEW:
|
||
render->SwitchView(command.param1);
|
||
break;
|
||
case CMD_EXIT:
|
||
isRunning_ = false;
|
||
break;
|
||
}
|
||
}
|
||
if (!isRunning_) {
|
||
break;
|
||
}
|
||
// 渲染
|
||
eglSubCore->makeCurrent(thrInfo.eglCore->GetEGLDisplay());
|
||
render->render();
|
||
eglSubCore->swapBuffers(thrInfo.eglCore->GetEGLDisplay());
|
||
// 调用渲染完成回调
|
||
Callback callback;
|
||
{
|
||
std::lock_guard<std::mutex> lock(callbackMutex_);
|
||
callback = renderCompleteCallback_;
|
||
}
|
||
|
||
if (callback) {
|
||
callback();
|
||
}
|
||
|
||
// 控制帧率
|
||
usleep(16667); // ~60 FPS
|
||
}
|
||
}
|
||
|
||
void RenderThread::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 RenderThread::setRotation(float xAngle, float yAngle) {
|
||
std::lock_guard<std::mutex> lock(commandMutex_);
|
||
render->setRotation(xAngle,yAngle);
|
||
}
|
||
|
||
void RenderThread::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();
|
||
render->SetMoveTo(x,y);
|
||
}
|
||
|
||
void RenderThread::resetView() {
|
||
std::lock_guard<std::mutex> lock(commandMutex_);
|
||
commandQueue_.push(RenderCommand(CMD_RESET_VIEW));
|
||
commandCondition_.notify_one();
|
||
}
|
||
void RenderThread::swicthView(std::string strView) {
|
||
std::lock_guard<std::mutex> lock(commandMutex_);
|
||
RenderCommand cmd(CMD_SWITCH_VIEW);
|
||
cmd.param1 = strView;
|
||
commandQueue_.push(RenderCommand(cmd));
|
||
commandCondition_.notify_one();
|
||
}
|
||
void RenderThread::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 RenderThread::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();
|
||
rdWidth = static_cast<float>(width);
|
||
rdHeight = static_cast<float>(height);
|
||
render->resize(rdWidth,rdHeight);
|
||
}
|
||
|
||
void RenderThread::registerRenderCompleteCallback(Callback callback) {
|
||
std::lock_guard<std::mutex> lock(callbackMutex_);
|
||
renderCompleteCallback_ = callback;
|
||
}
|
||
} // namespace OCCTRenderer
|