完善渲染整体逻辑.
已知BUG.OCCT的view没有绑定鸿蒙OHWindows*的窗口对象
This commit is contained in:
parent
77dd6edf5f
commit
eed0b54b30
@ -28,14 +28,16 @@ endforeach()
|
|||||||
# 添加源文件
|
# 添加源文件
|
||||||
add_library(opencax SHARED
|
add_library(opencax SHARED
|
||||||
# Header
|
# Header
|
||||||
NativeEGLOCCT/EGLConst.h
|
|
||||||
NativeEGLOCCT/EGLCore.h
|
NativeEGLOCCT/EGLCore.h
|
||||||
|
NativeEGLOCCT/NativeRender.h
|
||||||
|
NativeEGLOCCT/NativeRenderThread.h
|
||||||
NativeEGLOCCT/NativeManager.h
|
NativeEGLOCCT/NativeManager.h
|
||||||
# Cpp Src
|
# Cpp Src
|
||||||
NativeEGLOCCT/EGLCore.cpp
|
NativeEGLOCCT/EGLCore.cpp
|
||||||
|
NativeEGLOCCT/NativeRender.cpp
|
||||||
|
NativeEGLOCCT/NativeRenderThread.cpp
|
||||||
NativeEGLOCCT/NativeManager.cpp
|
NativeEGLOCCT/NativeManager.cpp
|
||||||
napi_init.cpp
|
napi_init.cpp)
|
||||||
)
|
|
||||||
|
|
||||||
# 查找系统库
|
# 查找系统库
|
||||||
find_library(EGL-lib EGL)
|
find_library(EGL-lib EGL)
|
||||||
|
|||||||
@ -1,159 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) 2025 Huawei Device Co., Ltd.
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef NATIVEXCOMPONENT_EGLCONST_H
|
|
||||||
#define NATIVEXCOMPONENT_EGLCONST_H
|
|
||||||
// [Start egl_const_h]
|
|
||||||
// EGLConst.h
|
|
||||||
#include <EGL/egl.h>
|
|
||||||
#include <EGL/eglext.h>
|
|
||||||
#include <GLES3/gl3.h>
|
|
||||||
|
|
||||||
const unsigned int LOG_PRINT_DOMAIN = 0xFF00;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Program 错误
|
|
||||||
*/
|
|
||||||
const GLuint PROGRAM_ERROR = 0;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 位置错误。
|
|
||||||
*/
|
|
||||||
const GLint POSITION_ERROR = -1;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 默认x坐标。
|
|
||||||
*/
|
|
||||||
const int DEFAULT_X_POSITION = 0;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 默认y坐标。
|
|
||||||
*/
|
|
||||||
const int DEFAULT_Y_POSITION = 0;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Gl 红色默认值。
|
|
||||||
*/
|
|
||||||
const GLfloat GL_RED_DEFAULT = 0.0;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Gl 绿色默认值。
|
|
||||||
*/
|
|
||||||
const GLfloat GL_GREEN_DEFAULT = 0.0;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Gl 蓝色默认值。
|
|
||||||
*/
|
|
||||||
const GLfloat GL_BLUE_DEFAULT = 0.0;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Gl 透明度。
|
|
||||||
*/
|
|
||||||
const GLfloat GL_ALPHA_DEFAULT = 1.0;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Pointer 数量。
|
|
||||||
*/
|
|
||||||
const GLint POINTER_SIZE = 2;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Triangle fan 尺寸。
|
|
||||||
*/
|
|
||||||
const GLsizei TRIANGLE_FAN_SIZE = 4;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 50%。
|
|
||||||
*/
|
|
||||||
const float FIFTY_PERCENT = 0.5;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 位置句柄名字。
|
|
||||||
*/
|
|
||||||
const char POSITION_NAME[] = "a_position";
|
|
||||||
|
|
||||||
// [StartExclude egl_const_h]
|
|
||||||
/**
|
|
||||||
* numeric value 0.
|
|
||||||
*/
|
|
||||||
const int NUM_0 = 0;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* numeric value 4.
|
|
||||||
*/
|
|
||||||
const int NUM_4 = 4;
|
|
||||||
// [EndExclude egl_const_h]
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 背景色 #f4f4f4.
|
|
||||||
*/
|
|
||||||
const GLfloat BACKGROUND_COLOR[] = {244.0f / 255, 244.0f / 255, 244.0f / 255, 1.0f};
|
|
||||||
|
|
||||||
// [StartExclude egl_const_h]
|
|
||||||
/**
|
|
||||||
* Background color #ffffff00.
|
|
||||||
*/
|
|
||||||
const GLfloat TRANSPARENT_COLOR[] = {255.0f / 255, 255.0f / 255, 255.0f / 255, 0.0f};
|
|
||||||
// [EndExclude egl_const_h]
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Draw 颜色 #7E8FFB.
|
|
||||||
*/
|
|
||||||
const GLfloat DRAW_COLOR[] = {126.0f / 255, 143.0f / 255, 251.0f / 255, 1.0f};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Change 颜色 #92D6CC.
|
|
||||||
*/
|
|
||||||
const GLfloat CHANGE_COLOR[] = {146.0f / 255, 214.0f / 255, 204.0f / 255, 1.0f};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 背景区域。
|
|
||||||
*/
|
|
||||||
const GLfloat BACKGROUND_RECTANGLE_VERTICES[] = {-1.0f, 1.0f, 1.0f, 1.0f, 1.0f, -1.0f, -1.0f, -1.0f};
|
|
||||||
|
|
||||||
const EGLint ATTRIB_LIST[] = {
|
|
||||||
// 键,值。
|
|
||||||
EGL_SURFACE_TYPE, EGL_WINDOW_BIT, EGL_RED_SIZE, 8, EGL_GREEN_SIZE, 8, EGL_BLUE_SIZE, 8, EGL_ALPHA_SIZE, 8,
|
|
||||||
EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,
|
|
||||||
// 结束。
|
|
||||||
EGL_NONE};
|
|
||||||
|
|
||||||
const EGLint CONTEXT_ATTRIBS[] = {EGL_CONTEXT_CLIENT_VERSION, 2, EGL_NONE};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 顶点着色器
|
|
||||||
*/
|
|
||||||
const char VERTEX_SHADER[] = "#version 300 es\n"
|
|
||||||
"layout(location = 0) in vec4 a_position;\n"
|
|
||||||
"layout(location = 1) in vec4 a_color; \n"
|
|
||||||
"out vec4 v_color; \n"
|
|
||||||
"void main() \n"
|
|
||||||
"{ \n"
|
|
||||||
" gl_Position = a_position; \n"
|
|
||||||
" v_color = a_color; \n"
|
|
||||||
"} \n";
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 片元着色器。
|
|
||||||
*/
|
|
||||||
const char FRAGMENT_SHADER[] = "#version 300 es\n"
|
|
||||||
"precision mediump float; \n"
|
|
||||||
"in vec4 v_color; \n"
|
|
||||||
"out vec4 fragColor; \n"
|
|
||||||
"void main() \n"
|
|
||||||
"{ \n"
|
|
||||||
" fragColor = v_color; \n"
|
|
||||||
"} \n";
|
|
||||||
// [End egl_const_h]
|
|
||||||
#endif // NATIVEXCOMPONENT_EGLCONST_H
|
|
||||||
@ -1,646 +1,119 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) 2025 Huawei Device Co., Ltd.
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "EGLCore.h"
|
#include "EGLCore.h"
|
||||||
|
|
||||||
#include <EGL/egl.h>
|
|
||||||
#include <EGL/eglext.h>
|
|
||||||
#include <EGL/eglplatform.h>
|
|
||||||
#include <GLES3/gl3.h>
|
|
||||||
#include <cmath>
|
|
||||||
#include <cstdio>
|
#include <cstdio>
|
||||||
#include <hilog/log.h>
|
#include <cstring>
|
||||||
|
|
||||||
#include "common.h"
|
|
||||||
|
|
||||||
namespace NativeOpenCAX {
|
namespace NativeOpenCAX {
|
||||||
namespace {
|
|
||||||
constexpr int32_t NUM_4 = 4;
|
|
||||||
/**
|
|
||||||
* Vertex shader.
|
|
||||||
*/
|
|
||||||
const char VERTEX_SHADER[] = "#version 300 es\n"
|
|
||||||
"layout(location = 0) in vec4 a_position;\n"
|
|
||||||
"layout(location = 1) in vec4 a_color; \n"
|
|
||||||
"out vec4 v_color; \n"
|
|
||||||
"void main() \n"
|
|
||||||
"{ \n"
|
|
||||||
" gl_Position = a_position; \n"
|
|
||||||
" v_color = a_color; \n"
|
|
||||||
"} \n";
|
|
||||||
|
|
||||||
/**
|
EGLCore::EGLCore()
|
||||||
* Fragment shader.
|
: eglDisplay_(EGL_NO_DISPLAY),
|
||||||
*/
|
eglContext_(EGL_NO_CONTEXT),
|
||||||
const char FRAGMENT_SHADER[] = "#version 300 es\n"
|
eglSurface_(EGL_NO_SURFACE),
|
||||||
"precision mediump float; \n"
|
nativeWindow_(nullptr) {}
|
||||||
"in vec4 v_color; \n"
|
|
||||||
"out vec4 fragColor; \n"
|
|
||||||
"void main() \n"
|
|
||||||
"{ \n"
|
|
||||||
" fragColor = v_color; \n"
|
|
||||||
"} \n";
|
|
||||||
// [Start native_color]
|
|
||||||
/**
|
|
||||||
* 绘制背景颜色 #f4f4f4.
|
|
||||||
*/
|
|
||||||
const GLfloat BACKGROUND_COLOR[] = {244.0f / 255, 244.0f / 255, 244.0f / 255, 1.0f};
|
|
||||||
|
|
||||||
/**
|
EGLCore::~EGLCore() {
|
||||||
* 绘制图案颜色 #7E8FFB.
|
destroy();
|
||||||
*/
|
}
|
||||||
const GLfloat DRAW_COLOR[] = {126.0f / 255, 143.0f / 255, 251.0f / 255, 1.0f};
|
|
||||||
|
|
||||||
/**
|
bool EGLCore::init(OHNativeWindow* window) {
|
||||||
* 绘制图案改变后的颜色 #92D6CC.
|
if (!window) {
|
||||||
*/
|
printf("Native window is null\n");
|
||||||
const GLfloat CHANGE_COLOR[] = {146.0f / 255, 214.0f / 255, 204.0f / 255, 1.0f};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 绘制背景顶点
|
|
||||||
*/
|
|
||||||
const GLfloat BACKGROUND_RECTANGLE_VERTICES[] = {
|
|
||||||
-1.0f, 1.0f,
|
|
||||||
1.0f, 1.0f,
|
|
||||||
1.0f, -1.0f,
|
|
||||||
-1.0f, -1.0f};
|
|
||||||
// [End native_color]
|
|
||||||
/**
|
|
||||||
* Get context parameter count.
|
|
||||||
*/
|
|
||||||
const size_t GET_CONTEXT_PARAM_CNT = 1;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Fifty percent.
|
|
||||||
*/
|
|
||||||
const float FIFTY_PERCENT = 0.5;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Pointer size.
|
|
||||||
*/
|
|
||||||
const GLint POINTER_SIZE = 2;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Triangle fan size.
|
|
||||||
*/
|
|
||||||
const GLsizei TRIANGLE_FAN_SIZE = 4;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Egl red size default.
|
|
||||||
*/
|
|
||||||
const int EGL_RED_SIZE_DEFAULT = 8;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Egl green size default.
|
|
||||||
*/
|
|
||||||
const int EGL_GREEN_SIZE_DEFAULT = 8;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Egl blue size default.
|
|
||||||
*/
|
|
||||||
const int EGL_BLUE_SIZE_DEFAULT = 8;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Egl alpha size default.
|
|
||||||
*/
|
|
||||||
const int EGL_ALPHA_SIZE_DEFAULT = 8;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Default x position.
|
|
||||||
*/
|
|
||||||
const int DEFAULT_X_POSITION = 0;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Default y position.
|
|
||||||
*/
|
|
||||||
const int DEFAULT_Y_POSITION = 0;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Gl red default.
|
|
||||||
*/
|
|
||||||
const GLfloat GL_RED_DEFAULT = 0.0;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Gl green default.
|
|
||||||
*/
|
|
||||||
const GLfloat GL_GREEN_DEFAULT = 0.0;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Gl blue default.
|
|
||||||
*/
|
|
||||||
const GLfloat GL_BLUE_DEFAULT = 0.0;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Gl alpha default.
|
|
||||||
*/
|
|
||||||
const GLfloat GL_ALPHA_DEFAULT = 1.0;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Program error.
|
|
||||||
*/
|
|
||||||
const GLuint PROGRAM_ERROR = 0;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Shape vertices size.
|
|
||||||
*/
|
|
||||||
const int SHAPE_VERTICES_SIZE = 8;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Position handle name.
|
|
||||||
*/
|
|
||||||
const char POSITION_NAME[] = "a_position";
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Position error.
|
|
||||||
*/
|
|
||||||
const GLint POSITION_ERROR = -1;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Config attribute list.
|
|
||||||
*/
|
|
||||||
const EGLint ATTRIB_LIST[] = {
|
|
||||||
// Key,value.
|
|
||||||
EGL_SURFACE_TYPE, EGL_WINDOW_BIT,
|
|
||||||
EGL_RED_SIZE, EGL_RED_SIZE_DEFAULT,
|
|
||||||
EGL_GREEN_SIZE, EGL_GREEN_SIZE_DEFAULT,
|
|
||||||
EGL_BLUE_SIZE, EGL_BLUE_SIZE_DEFAULT,
|
|
||||||
EGL_ALPHA_SIZE, EGL_ALPHA_SIZE_DEFAULT,
|
|
||||||
EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,
|
|
||||||
// End.
|
|
||||||
EGL_NONE};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Context attributes.
|
|
||||||
*/
|
|
||||||
const EGLint CONTEXT_ATTRIBS[] = {
|
|
||||||
EGL_CONTEXT_CLIENT_VERSION, 2,
|
|
||||||
EGL_NONE};
|
|
||||||
} // namespace
|
|
||||||
// [Start native_create_context_init]
|
|
||||||
bool EGLCore::EglContextInit(void* window, int width, int height)
|
|
||||||
{
|
|
||||||
// [StartExclude native_create_context_init]
|
|
||||||
OH_LOG_Print(LOG_APP, LOG_INFO, LOG_PRINT_DOMAIN, "EGLCore", "EglContextInit execute");
|
|
||||||
if ((window == nullptr) || (width <= 0) || (height <= 0)) {
|
|
||||||
OH_LOG_Print(LOG_APP, LOG_ERROR, LOG_PRINT_DOMAIN, "EGLCore", "EglContextInit: param error");
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
// [EndExclude native_create_context_init]
|
|
||||||
UpdateSize(width, height);
|
|
||||||
eglWindow_ = static_cast<EGLNativeWindowType>(window);
|
|
||||||
|
|
||||||
// 初始化display
|
nativeWindow_ = window;
|
||||||
|
|
||||||
|
// 获取EGL display
|
||||||
eglDisplay_ = eglGetDisplay(EGL_DEFAULT_DISPLAY);
|
eglDisplay_ = eglGetDisplay(EGL_DEFAULT_DISPLAY);
|
||||||
if (eglDisplay_ == EGL_NO_DISPLAY) {
|
if (eglDisplay_ == EGL_NO_DISPLAY) {
|
||||||
OH_LOG_Print(LOG_APP, LOG_ERROR, LOG_PRINT_DOMAIN, "EGLCore", "eglGetDisplay: unable to get EGL display");
|
printf("eglGetDisplay failed\n");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 初始化EGL
|
// 初始化EGL
|
||||||
EGLint majorVersion;
|
if (!eglInitialize(eglDisplay_, nullptr, nullptr)) {
|
||||||
EGLint minorVersion;
|
printf("eglInitialize failed\n");
|
||||||
if (!eglInitialize(eglDisplay_, &majorVersion, &minorVersion)) {
|
|
||||||
OH_LOG_Print(
|
|
||||||
LOG_APP, LOG_ERROR, LOG_PRINT_DOMAIN, "EGLCore", "eglInitialize: unable to get initialize EGL display");
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 选择配置
|
// 配置EGL
|
||||||
const EGLint maxConfigSize = 1;
|
EGLint attribs[] = {
|
||||||
|
EGL_SURFACE_TYPE, EGL_WINDOW_BIT,
|
||||||
|
EGL_RENDERABLE_TYPE, EGL_OPENGL_ES3_BIT,
|
||||||
|
EGL_BLUE_SIZE, 8,
|
||||||
|
EGL_GREEN_SIZE, 8,
|
||||||
|
EGL_RED_SIZE, 8,
|
||||||
|
EGL_ALPHA_SIZE, 8,
|
||||||
|
EGL_DEPTH_SIZE, 16,
|
||||||
|
EGL_STENCIL_SIZE, 0,
|
||||||
|
EGL_NONE
|
||||||
|
};
|
||||||
|
|
||||||
EGLint numConfigs;
|
EGLint numConfigs;
|
||||||
if (!eglChooseConfig(eglDisplay_, ATTRIB_LIST, &eglConfig_, maxConfigSize, &numConfigs)) {
|
if (!eglChooseConfig(eglDisplay_, attribs, &eglConfig_, 1, &numConfigs) || numConfigs == 0) {
|
||||||
OH_LOG_Print(LOG_APP, LOG_ERROR, LOG_PRINT_DOMAIN, "EGLCore", "eglChooseConfig: unable to choose configs");
|
printf("eglChooseConfig failed\n");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
// 创建环境
|
|
||||||
return CreateEnvironment();
|
// 创建EGL surface
|
||||||
}
|
eglSurface_ = eglCreateWindowSurface(eglDisplay_, eglConfig_, (NativeWindowType)nativeWindow_, nullptr);
|
||||||
// [End native_create_context_init]
|
if (eglSurface_ == EGL_NO_SURFACE) {
|
||||||
// [Start native_create_environment]
|
printf("eglCreateWindowSurface failed: 0x%x\n", eglGetError());
|
||||||
bool EGLCore::CreateEnvironment()
|
|
||||||
{
|
|
||||||
// 创建Surface
|
|
||||||
if (eglWindow_ == nullptr) {
|
|
||||||
OH_LOG_Print(LOG_APP, LOG_ERROR, LOG_PRINT_DOMAIN, "EGLCore", "eglWindow_ is null");
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
eglSurface_ = eglCreateWindowSurface(eglDisplay_, eglConfig_, eglWindow_, NULL);
|
|
||||||
if (eglSurface_ == nullptr) {
|
// 创建EGL context
|
||||||
OH_LOG_Print(
|
EGLint contextAttribs[] = {
|
||||||
LOG_APP, LOG_ERROR, LOG_PRINT_DOMAIN, "EGLCore", "eglCreateWindowSurface: unable to create surface");
|
EGL_CONTEXT_CLIENT_VERSION, 3,
|
||||||
|
EGL_NONE
|
||||||
|
};
|
||||||
|
|
||||||
|
eglContext_ = eglCreateContext(eglDisplay_, eglConfig_, EGL_NO_CONTEXT, contextAttribs);
|
||||||
|
if (eglContext_ == EGL_NO_CONTEXT) {
|
||||||
|
printf("eglCreateContext failed\n");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
// 创建context
|
|
||||||
eglContext_ = eglCreateContext(eglDisplay_, eglConfig_, EGL_NO_CONTEXT, CONTEXT_ATTRIBS);
|
// 激活上下文
|
||||||
|
makeCurrent();
|
||||||
|
|
||||||
|
// 检查GL错误
|
||||||
|
GLenum glError = glGetError();
|
||||||
|
if (glError != GL_NO_ERROR) {
|
||||||
|
printf("OpenGL error after initialization: 0x%x\n", glError);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 设置GL视口
|
||||||
|
glViewport(0, 0, 1280, 720); // 默认大小,实际会随窗口变化
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void EGLCore::makeCurrent() {
|
||||||
if (!eglMakeCurrent(eglDisplay_, eglSurface_, eglSurface_, eglContext_)) {
|
if (!eglMakeCurrent(eglDisplay_, eglSurface_, eglSurface_, eglContext_)) {
|
||||||
OH_LOG_Print(LOG_APP, LOG_ERROR, LOG_PRINT_DOMAIN, "EGLCore", "eglMakeCurrent failed");
|
printf("eglMakeCurrent failed: 0x%x\n", eglGetError());
|
||||||
return false;
|
|
||||||
}
|
|
||||||
// 创建program
|
|
||||||
program_ = CreateProgram(VERTEX_SHADER, FRAGMENT_SHADER);
|
|
||||||
if (program_ == PROGRAM_ERROR) {
|
|
||||||
OH_LOG_Print(LOG_APP, LOG_ERROR, LOG_PRINT_DOMAIN, "EGLCore", "CreateProgram: unable to create program");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
// [End native_create_environment]
|
|
||||||
// [Start native_background]
|
|
||||||
// 绘制背景颜色
|
|
||||||
void EGLCore::Background()
|
|
||||||
{
|
|
||||||
GLint position = PrepareDraw();
|
|
||||||
if (position == POSITION_ERROR) {
|
|
||||||
OH_LOG_Print(LOG_APP, LOG_ERROR, LOG_PRINT_DOMAIN, "EGLCore", "Background get position failed");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!ExecuteDraw(position, BACKGROUND_COLOR,
|
|
||||||
BACKGROUND_RECTANGLE_VERTICES, sizeof(BACKGROUND_RECTANGLE_VERTICES))) {
|
|
||||||
OH_LOG_Print(LOG_APP, LOG_ERROR, LOG_PRINT_DOMAIN, "EGLCore", "Background execute draw failed");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!FinishDraw()) {
|
|
||||||
OH_LOG_Print(LOG_APP, LOG_ERROR, LOG_PRINT_DOMAIN, "EGLCore", "Background FinishDraw failed");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// [End native_background]
|
|
||||||
// [Start native_draw]
|
|
||||||
void EGLCore::Draw(int& hasDraw)
|
|
||||||
{
|
|
||||||
flag_ = false;
|
|
||||||
OH_LOG_Print(LOG_APP, LOG_INFO, LOG_PRINT_DOMAIN, "EGLCore", "Draw");
|
|
||||||
GLint position = PrepareDraw();
|
|
||||||
if (position == POSITION_ERROR) {
|
|
||||||
OH_LOG_Print(LOG_APP, LOG_ERROR, LOG_PRINT_DOMAIN, "EGLCore", "Draw get position failed");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 绘制背景
|
|
||||||
if (!ExecuteDraw(position, BACKGROUND_COLOR,
|
|
||||||
BACKGROUND_RECTANGLE_VERTICES, sizeof(BACKGROUND_RECTANGLE_VERTICES))) {
|
|
||||||
OH_LOG_Print(LOG_APP, LOG_ERROR, LOG_PRINT_DOMAIN, "EGLCore", "Draw execute draw background failed");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 将五角星分为五个四边形,计算其中一个四边形的四个顶点
|
|
||||||
GLfloat rotateX = 0;
|
|
||||||
GLfloat rotateY = FIFTY_PERCENT * height_;
|
|
||||||
GLfloat centerX = 0;
|
|
||||||
// Convert DEG(54° & 18°) to RAD
|
|
||||||
GLfloat centerY = -rotateY * (M_PI / 180 * 54) * (M_PI / 180 * 18);
|
|
||||||
// Convert DEG(18°) to RAD
|
|
||||||
GLfloat leftX = -rotateY * (M_PI / 180 * 18);
|
|
||||||
GLfloat leftY = 0;
|
|
||||||
// Convert DEG(18°) to RAD
|
|
||||||
GLfloat rightX = rotateY * (M_PI / 180 * 18);
|
|
||||||
GLfloat rightY = 0;
|
|
||||||
|
|
||||||
// 确定绘制四边形的顶点,使用绘制区域的百分比表示
|
|
||||||
const GLfloat shapeVertices[] = { centerX / width_, centerY / height_, leftX / width_, leftY / height_,
|
|
||||||
rotateX / width_, rotateY / height_, rightX / width_, rightY / height_ };
|
|
||||||
|
|
||||||
if (!ExecuteDrawStar(position, DRAW_COLOR, shapeVertices, sizeof(shapeVertices))) {
|
|
||||||
OH_LOG_Print(LOG_APP, LOG_ERROR, LOG_PRINT_DOMAIN, "EGLCore", "Draw execute draw shape failed");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Convert DEG(72°) to RAD
|
|
||||||
GLfloat rad = M_PI / 180 * 72;
|
|
||||||
// Rotate four times
|
|
||||||
// 在文件egl_core.cpp中定义,NUM_4的值为4
|
|
||||||
for (int i = 0; i < NUM_4; ++i) {
|
|
||||||
// 旋转得其他四个四边形的顶点
|
|
||||||
Rotate2d(centerX, centerY, &rotateX, &rotateY, rad);
|
|
||||||
Rotate2d(centerX, centerY, &leftX, &leftY, rad);
|
|
||||||
Rotate2d(centerX, centerY, &rightX, &rightY, rad);
|
|
||||||
|
|
||||||
// 确定绘制四边形的顶点,使用绘制区域的百分比表示
|
|
||||||
const GLfloat shapeVertices[] = { centerX / width_, centerY / height_, leftX / width_, leftY / height_,
|
|
||||||
rotateX / width_, rotateY / height_, rightX / width_, rightY / height_ };
|
|
||||||
|
|
||||||
// 绘制图形
|
|
||||||
if (!ExecuteDrawStar(position, DRAW_COLOR, shapeVertices, sizeof(shapeVertices))) {
|
|
||||||
OH_LOG_Print(LOG_APP, LOG_ERROR, LOG_PRINT_DOMAIN, "EGLCore", "Draw execute draw shape failed");
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 结束绘制
|
bool EGLCore::swapBuffers() {
|
||||||
if (!FinishDraw()) {
|
|
||||||
OH_LOG_Print(LOG_APP, LOG_ERROR, LOG_PRINT_DOMAIN, "EGLCore", "Draw FinishDraw failed");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
hasDraw = 1;
|
|
||||||
|
|
||||||
flag_ = true;
|
|
||||||
}
|
|
||||||
// [End native_draw]
|
|
||||||
// [Start native_change_color]
|
|
||||||
void EGLCore::ChangeColor(int& hasChangeColor)
|
|
||||||
{
|
|
||||||
if (!flag_) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
OH_LOG_Print(LOG_APP, LOG_INFO, LOG_PRINT_DOMAIN, "EGLCore", "ChangeColor");
|
|
||||||
GLint position = PrepareDraw();
|
|
||||||
if (position == POSITION_ERROR) {
|
|
||||||
OH_LOG_Print(LOG_APP, LOG_ERROR, LOG_PRINT_DOMAIN, "EGLCore", "ChangeColor get position failed");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 绘制背景
|
|
||||||
if (!ExecuteDraw(position, BACKGROUND_COLOR,
|
|
||||||
BACKGROUND_RECTANGLE_VERTICES, sizeof(BACKGROUND_RECTANGLE_VERTICES))) {
|
|
||||||
OH_LOG_Print(LOG_APP, LOG_ERROR, LOG_PRINT_DOMAIN, "EGLCore", "ChangeColor execute draw background failed");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 确定绘制四边形的顶点,使用绘制区域的百分比表示
|
|
||||||
GLfloat rotateX = 0;
|
|
||||||
GLfloat rotateY = FIFTY_PERCENT * height_;
|
|
||||||
GLfloat centerX = 0;
|
|
||||||
// Convert DEG(54° & 18°) to RAD
|
|
||||||
GLfloat centerY = -rotateY * (M_PI / 180 * 54) * (M_PI / 180 * 18);
|
|
||||||
// Convert DEG(18°) to RAD
|
|
||||||
GLfloat leftX = -rotateY * (M_PI / 180 * 18);
|
|
||||||
GLfloat leftY = 0;
|
|
||||||
// Convert DEG(18°) to RAD
|
|
||||||
GLfloat rightX = rotateY * (M_PI / 180 * 18);
|
|
||||||
GLfloat rightY = 0;
|
|
||||||
|
|
||||||
// 确定绘制四边形的顶点,使用绘制区域的百分比表示
|
|
||||||
const GLfloat shapeVertices[] = { centerX / width_, centerY / height_, leftX / width_, leftY / height_,
|
|
||||||
rotateX / width_, rotateY / height_, rightX / width_, rightY / height_ };
|
|
||||||
|
|
||||||
// 使用新的颜色绘制
|
|
||||||
if (!ExecuteDrawNewStar(0, CHANGE_COLOR, shapeVertices, sizeof(shapeVertices))) {
|
|
||||||
OH_LOG_Print(LOG_APP, LOG_ERROR, LOG_PRINT_DOMAIN, "EGLCore", "Draw execute draw shape failed");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Convert DEG(72°) to RAD
|
|
||||||
GLfloat rad = M_PI / 180 * 72;
|
|
||||||
// Rotate four times
|
|
||||||
// 在文件egl_core.cpp中定义,NUM_4的值为4
|
|
||||||
for (int i = 0; i < NUM_4; ++i) {
|
|
||||||
// 旋转得其他四个四边形的顶点
|
|
||||||
Rotate2d(centerX, centerY, &rotateX, &rotateY, rad);
|
|
||||||
Rotate2d(centerX, centerY, &leftX, &leftY, rad);
|
|
||||||
Rotate2d(centerX, centerY, &rightX, &rightY, rad);
|
|
||||||
// 确定绘制四边形的顶点,使用绘制区域的百分比表示
|
|
||||||
const GLfloat shapeVertices[] = { centerX / width_, centerY / height_, leftX / width_, leftY / height_,
|
|
||||||
rotateX / width_, rotateY / height_, rightX / width_, rightY / height_ };
|
|
||||||
|
|
||||||
// 使用新的颜色绘制
|
|
||||||
if (!ExecuteDrawNewStar(position, CHANGE_COLOR, shapeVertices, sizeof(shapeVertices))) {
|
|
||||||
OH_LOG_Print(LOG_APP, LOG_ERROR, LOG_PRINT_DOMAIN, "EGLCore", "Draw execute draw shape failed");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// 结束绘制
|
|
||||||
if (!FinishDraw()) {
|
|
||||||
OH_LOG_Print(LOG_APP, LOG_ERROR, LOG_PRINT_DOMAIN, "EGLCore", "ChangeColor FinishDraw failed");
|
|
||||||
}
|
|
||||||
hasChangeColor = 1;
|
|
||||||
}
|
|
||||||
// [StartExclude native_change_color]
|
|
||||||
// [Start native_prepare_draw]
|
|
||||||
// 绘前准备,获取position,创建成功时position值从0开始
|
|
||||||
GLint EGLCore::PrepareDraw()
|
|
||||||
{
|
|
||||||
if ((eglDisplay_ == nullptr) || (eglSurface_ == nullptr) || (eglContext_ == nullptr) ||
|
|
||||||
(!eglMakeCurrent(eglDisplay_, eglSurface_, eglSurface_, eglContext_))) {
|
|
||||||
OH_LOG_Print(LOG_APP, LOG_ERROR, LOG_PRINT_DOMAIN, "EGLCore", "PrepareDraw: param error");
|
|
||||||
return POSITION_ERROR;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 该gl函数没有返回值。
|
|
||||||
glViewport(DEFAULT_X_POSITION, DEFAULT_Y_POSITION, width_, height_);
|
|
||||||
glClearColor(GL_RED_DEFAULT, GL_GREEN_DEFAULT, GL_BLUE_DEFAULT, GL_ALPHA_DEFAULT);
|
|
||||||
glClear(GL_COLOR_BUFFER_BIT);
|
|
||||||
glUseProgram(program_);
|
|
||||||
|
|
||||||
return glGetAttribLocation(program_, POSITION_NAME);
|
|
||||||
}
|
|
||||||
// [End native_prepare_draw]
|
|
||||||
// [Start native_execute_draw]
|
|
||||||
// 依据传入参数在指定区域绘制指定颜色
|
|
||||||
bool EGLCore::ExecuteDraw(GLint position, const GLfloat* color, const GLfloat shapeVertices[], unsigned long vertSize)
|
|
||||||
{
|
|
||||||
if ((position > 0) || (color == nullptr) || (vertSize / sizeof(shapeVertices[0])) != SHAPE_VERTICES_SIZE) {
|
|
||||||
OH_LOG_Print(LOG_APP, LOG_ERROR, LOG_PRINT_DOMAIN, "EGLCore", "ExecuteDraw: param error");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 该gl函数没有返回值。
|
|
||||||
glVertexAttribPointer(position, POINTER_SIZE, GL_FLOAT, GL_FALSE, 0, shapeVertices);
|
|
||||||
glEnableVertexAttribArray(position);
|
|
||||||
glVertexAttrib4fv(1, color);
|
|
||||||
glDrawArrays(GL_TRIANGLE_FAN, 0, TRIANGLE_FAN_SIZE);
|
|
||||||
glDisableVertexAttribArray(position);
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
// [End native_execute_draw]
|
|
||||||
bool EGLCore::ExecuteDrawStar(
|
|
||||||
GLint position, const GLfloat* color, const GLfloat shapeVertices[], unsigned long vertSize)
|
|
||||||
{
|
|
||||||
if ((position > 0) || (color == nullptr) || (vertSize / sizeof(shapeVertices[0])) != SHAPE_VERTICES_SIZE) {
|
|
||||||
OH_LOG_Print(LOG_APP, LOG_ERROR, LOG_PRINT_DOMAIN, "EGLCore", "ExecuteDraw: param error");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// The gl function has no return value.
|
|
||||||
glVertexAttribPointer(position, POINTER_SIZE, GL_FLOAT, GL_FALSE, 0, shapeVertices);
|
|
||||||
glVertexAttribPointer(1, POINTER_SIZE, GL_FLOAT, GL_FALSE, 0, color);
|
|
||||||
glEnableVertexAttribArray(position);
|
|
||||||
glEnableVertexAttribArray(1);
|
|
||||||
glVertexAttrib4fv(1, color);
|
|
||||||
glDrawArrays(GL_TRIANGLE_FAN, 0, TRIANGLE_FAN_SIZE);
|
|
||||||
glDisableVertexAttribArray(position);
|
|
||||||
glDisableVertexAttribArray(1);
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
// [EndExclude native_change_color]
|
|
||||||
bool EGLCore::ExecuteDrawNewStar(
|
|
||||||
GLint position, const GLfloat* color, const GLfloat shapeVertices[], unsigned long vertSize)
|
|
||||||
{
|
|
||||||
if ((position > 0) || (color == nullptr) || (vertSize / sizeof(shapeVertices[0])) != SHAPE_VERTICES_SIZE) {
|
|
||||||
OH_LOG_Print(LOG_APP, LOG_ERROR, LOG_PRINT_DOMAIN, "EGLCore", "ExecuteDraw: param error");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 该gl函数没有返回值。
|
|
||||||
glVertexAttribPointer(position, POINTER_SIZE, GL_FLOAT, GL_FALSE, 0, shapeVertices);
|
|
||||||
glEnableVertexAttribArray(position);
|
|
||||||
glVertexAttrib4fv(1, color);
|
|
||||||
glDrawArrays(GL_TRIANGLE_FAN, 0, TRIANGLE_FAN_SIZE);
|
|
||||||
glDisableVertexAttribArray(position);
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
// [End native_change_color]
|
|
||||||
void EGLCore::Rotate2d(GLfloat centerX, GLfloat centerY, GLfloat* rotateX, GLfloat* rotateY, GLfloat theta)
|
|
||||||
{
|
|
||||||
GLfloat tempX = cos(theta) * (*rotateX - centerX) - sin(theta) * (*rotateY - centerY);
|
|
||||||
GLfloat tempY = sin(theta) * (*rotateX - centerX) + cos(theta) * (*rotateY - centerY);
|
|
||||||
*rotateX = tempX + centerX;
|
|
||||||
*rotateY = tempY + centerY;
|
|
||||||
}
|
|
||||||
// [Start native_finish_draw]
|
|
||||||
// 结束绘制操作
|
|
||||||
bool EGLCore::FinishDraw()
|
|
||||||
{
|
|
||||||
// 强制刷新缓冲
|
|
||||||
glFlush();
|
|
||||||
glFinish();
|
|
||||||
return eglSwapBuffers(eglDisplay_, eglSurface_);
|
return eglSwapBuffers(eglDisplay_, eglSurface_);
|
||||||
}
|
}
|
||||||
// [End native_finish_draw]
|
|
||||||
// [Start native_load_shader]
|
void EGLCore::destroy() {
|
||||||
GLuint EGLCore::LoadShader(GLenum type, const char* shaderSrc)
|
if (eglDisplay_ != EGL_NO_DISPLAY) {
|
||||||
{
|
if (eglContext_ != EGL_NO_CONTEXT) {
|
||||||
if ((type <= 0) || (shaderSrc == nullptr)) {
|
eglDestroyContext(eglDisplay_, eglContext_);
|
||||||
OH_LOG_Print(LOG_APP, LOG_ERROR, LOG_PRINT_DOMAIN, "EGLCore", "glCreateShader type or shaderSrc error");
|
eglContext_ = EGL_NO_CONTEXT;
|
||||||
return PROGRAM_ERROR;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
GLuint shader = glCreateShader(type);
|
if (eglSurface_ != EGL_NO_SURFACE) {
|
||||||
if (shader == 0) {
|
eglDestroySurface(eglDisplay_, eglSurface_);
|
||||||
OH_LOG_Print(LOG_APP, LOG_ERROR, LOG_PRINT_DOMAIN, "EGLCore", "glCreateShader unable to load shader");
|
eglSurface_ = EGL_NO_SURFACE;
|
||||||
return PROGRAM_ERROR;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// 该gl函数没有返回值。
|
eglTerminate(eglDisplay_);
|
||||||
glShaderSource(shader, 1, &shaderSrc, nullptr);
|
eglDisplay_ = EGL_NO_DISPLAY;
|
||||||
glCompileShader(shader);
|
}
|
||||||
|
|
||||||
GLint compiled;
|
|
||||||
glGetShaderiv(shader, GL_COMPILE_STATUS, &compiled);
|
|
||||||
if (compiled != 0) {
|
|
||||||
return shader;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
GLint infoLen = 0;
|
} // namespace NativeOpenCAX
|
||||||
glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &infoLen);
|
|
||||||
if (infoLen <= 1) {
|
|
||||||
glDeleteShader(shader);
|
|
||||||
return PROGRAM_ERROR;
|
|
||||||
}
|
|
||||||
|
|
||||||
char* infoLog = (char*)malloc(sizeof(char) * (infoLen + 1));
|
|
||||||
if (infoLog != nullptr) {
|
|
||||||
memset(infoLog, 0, infoLen + 1);
|
|
||||||
glGetShaderInfoLog(shader, infoLen, nullptr, infoLog);
|
|
||||||
OH_LOG_Print(LOG_APP, LOG_ERROR, LOG_PRINT_DOMAIN, "EGLCore", "glCompileShader error = %s", infoLog);
|
|
||||||
free(infoLog);
|
|
||||||
infoLog = nullptr;
|
|
||||||
}
|
|
||||||
glDeleteShader(shader);
|
|
||||||
return PROGRAM_ERROR;
|
|
||||||
}
|
|
||||||
// [End native_load_shader]
|
|
||||||
// [Start native_create_program]
|
|
||||||
GLuint EGLCore::CreateProgram(const char* vertexShader, const char* fragShader)
|
|
||||||
{
|
|
||||||
if ((vertexShader == nullptr) || (fragShader == nullptr)) {
|
|
||||||
OH_LOG_Print(
|
|
||||||
LOG_APP, LOG_ERROR, LOG_PRINT_DOMAIN, "EGLCore", "createProgram: vertexShader or fragShader is null");
|
|
||||||
return PROGRAM_ERROR;
|
|
||||||
}
|
|
||||||
|
|
||||||
GLuint vertex = LoadShader(GL_VERTEX_SHADER, vertexShader);
|
|
||||||
if (vertex == PROGRAM_ERROR) {
|
|
||||||
OH_LOG_Print(LOG_APP, LOG_ERROR, LOG_PRINT_DOMAIN, "EGLCore", "createProgram vertex error");
|
|
||||||
return PROGRAM_ERROR;
|
|
||||||
}
|
|
||||||
|
|
||||||
GLuint fragment = LoadShader(GL_FRAGMENT_SHADER, fragShader);
|
|
||||||
if (fragment == PROGRAM_ERROR) {
|
|
||||||
OH_LOG_Print(LOG_APP, LOG_ERROR, LOG_PRINT_DOMAIN, "EGLCore", "createProgram fragment error");
|
|
||||||
return PROGRAM_ERROR;
|
|
||||||
}
|
|
||||||
|
|
||||||
GLuint program = glCreateProgram();
|
|
||||||
if (program == PROGRAM_ERROR) {
|
|
||||||
OH_LOG_Print(LOG_APP, LOG_ERROR, LOG_PRINT_DOMAIN, "EGLCore", "createProgram program error");
|
|
||||||
glDeleteShader(vertex);
|
|
||||||
glDeleteShader(fragment);
|
|
||||||
return PROGRAM_ERROR;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 该gl函数没有返回值。
|
|
||||||
glAttachShader(program, vertex);
|
|
||||||
glAttachShader(program, fragment);
|
|
||||||
glLinkProgram(program);
|
|
||||||
|
|
||||||
GLint linked;
|
|
||||||
glGetProgramiv(program, GL_LINK_STATUS, &linked);
|
|
||||||
if (linked != 0) {
|
|
||||||
glDeleteShader(vertex);
|
|
||||||
glDeleteShader(fragment);
|
|
||||||
return program;
|
|
||||||
}
|
|
||||||
|
|
||||||
OH_LOG_Print(LOG_APP, LOG_ERROR, LOG_PRINT_DOMAIN, "EGLCore", "createProgram linked error");
|
|
||||||
GLint infoLen = 0;
|
|
||||||
glGetProgramiv(program, GL_INFO_LOG_LENGTH, &infoLen);
|
|
||||||
if (infoLen > 1) {
|
|
||||||
char* infoLog = (char*)malloc(sizeof(char) * (infoLen + 1));
|
|
||||||
memset(infoLog, 0, infoLen + 1);
|
|
||||||
glGetProgramInfoLog(program, infoLen, nullptr, infoLog);
|
|
||||||
OH_LOG_Print(LOG_APP, LOG_ERROR, LOG_PRINT_DOMAIN, "EGLCore", "glLinkProgram error = %s", infoLog);
|
|
||||||
free(infoLog);
|
|
||||||
infoLog = nullptr;
|
|
||||||
}
|
|
||||||
glDeleteShader(vertex);
|
|
||||||
glDeleteShader(fragment);
|
|
||||||
glDeleteProgram(program);
|
|
||||||
return PROGRAM_ERROR;
|
|
||||||
}
|
|
||||||
// [End native_create_program]
|
|
||||||
// [Start native_update_size]
|
|
||||||
void EGLCore::UpdateSize(int width, int height)
|
|
||||||
{
|
|
||||||
// width_和height_在头文件中定义
|
|
||||||
width_ = width;
|
|
||||||
height_ = height;
|
|
||||||
if (width_ > 0) {
|
|
||||||
widthPercent_ = FIFTY_PERCENT * height_ / width_;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// [End native_update_size]
|
|
||||||
// [Start native_release]
|
|
||||||
void EGLCore::Release()
|
|
||||||
{
|
|
||||||
// 释放Surface
|
|
||||||
if ((eglDisplay_ == nullptr) || (eglSurface_ == nullptr) || (!eglDestroySurface(eglDisplay_, eglSurface_))) {
|
|
||||||
OH_LOG_Print(LOG_APP, LOG_ERROR, LOG_PRINT_DOMAIN, "EGLCore", "Release eglDestroySurface failed");
|
|
||||||
}
|
|
||||||
// 释放context
|
|
||||||
if ((eglDisplay_ == nullptr) || (eglContext_ == nullptr) || (!eglDestroyContext(eglDisplay_, eglContext_))) {
|
|
||||||
OH_LOG_Print(LOG_APP, LOG_ERROR, LOG_PRINT_DOMAIN, "EGLCore", "Release eglDestroyContext failed");
|
|
||||||
}
|
|
||||||
// 释放display
|
|
||||||
if ((eglDisplay_ == nullptr) || (!eglTerminate(eglDisplay_))) {
|
|
||||||
OH_LOG_Print(LOG_APP, LOG_ERROR, LOG_PRINT_DOMAIN, "EGLCore", "Release eglTerminate failed");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// [End native_release]
|
|
||||||
} // namespace NativeXComponentSample
|
|
||||||
@ -12,49 +12,30 @@
|
|||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
#ifndef NATIVE_XCOMPONENT_EGL_CORE_H
|
#ifndef EGLCORE_H
|
||||||
#define NATIVE_XCOMPONENT_EGL_CORE_H
|
#define EGLCORE_H
|
||||||
|
|
||||||
#include <EGL/egl.h>
|
#include <EGL/egl.h>
|
||||||
#include <EGL/eglext.h>
|
|
||||||
#include <GLES3/gl3.h>
|
#include <GLES3/gl3.h>
|
||||||
#include "string"
|
#include <native_window/external_window.h>
|
||||||
|
|
||||||
namespace NativeOpenCAX {
|
namespace NativeOpenCAX {
|
||||||
class EGLCore {
|
class EGLCore {
|
||||||
public:
|
public:
|
||||||
explicit EGLCore() {}
|
EGLCore();
|
||||||
~EGLCore() {}
|
~EGLCore();
|
||||||
bool EglContextInit(void* window, int width, int height);
|
|
||||||
bool CreateEnvironment();
|
bool init(OHNativeWindow* window);
|
||||||
void Draw(int& hasDraw);
|
void makeCurrent();
|
||||||
void Background();
|
bool swapBuffers();
|
||||||
void ChangeColor(int& hasChangeColor);
|
void destroy();
|
||||||
void Release();
|
EGLSurface getSurface() const { return eglSurface_; }
|
||||||
void UpdateSize(int width, int height);
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
GLuint LoadShader(GLenum type, const char* shaderSrc);
|
EGLDisplay eglDisplay_;
|
||||||
GLuint CreateProgram(const char* vertexShader, const char* fragShader);
|
EGLContext eglContext_;
|
||||||
GLint PrepareDraw();
|
EGLSurface eglSurface_;
|
||||||
bool ExecuteDraw(GLint position, const GLfloat* color, const GLfloat shapeVertices[], unsigned long vertSize);
|
EGLConfig eglConfig_;
|
||||||
bool ExecuteDrawStar(GLint position, const GLfloat* color, const GLfloat shapeVertices[], unsigned long vertSize);
|
OHNativeWindow* nativeWindow_;
|
||||||
bool ExecuteDrawNewStar(GLint position, const GLfloat* color,
|
|
||||||
const GLfloat shapeVertices[], unsigned long vertSize);
|
|
||||||
void Rotate2d(GLfloat centerX, GLfloat centerY, GLfloat* rotateX, GLfloat* rotateY, GLfloat theta);
|
|
||||||
bool FinishDraw();
|
|
||||||
|
|
||||||
private:
|
|
||||||
EGLNativeWindowType eglWindow_;
|
|
||||||
EGLDisplay eglDisplay_ = EGL_NO_DISPLAY;
|
|
||||||
EGLConfig eglConfig_ = EGL_NO_CONFIG_KHR;
|
|
||||||
EGLSurface eglSurface_ = EGL_NO_SURFACE;
|
|
||||||
EGLContext eglContext_ = EGL_NO_CONTEXT;
|
|
||||||
GLuint program_;
|
|
||||||
bool flag_ = false;
|
|
||||||
int width_;
|
|
||||||
int height_;
|
|
||||||
GLfloat widthPercent_;
|
|
||||||
};
|
};
|
||||||
} // namespace NativeXComponentSample
|
} // namespace NativeOpenCAX
|
||||||
#endif // NATIVE_XCOMPONENT_EGL_CORE_H
|
#endif // EGLCORE_H
|
||||||
|
|||||||
@ -23,7 +23,7 @@
|
|||||||
#include "arkui/native_node_napi.h"
|
#include "arkui/native_node_napi.h"
|
||||||
#include "arkui/native_interface.h"
|
#include "arkui/native_interface.h"
|
||||||
#include "common.h"
|
#include "common.h"
|
||||||
|
#include <map>
|
||||||
#define COLUMN_MARGIN 10
|
#define COLUMN_MARGIN 10
|
||||||
#define XC_WIDTH 800
|
#define XC_WIDTH 800
|
||||||
#define XC_HEIGHT 600
|
#define XC_HEIGHT 600
|
||||||
@ -44,13 +44,17 @@ OH_NativeXComponent_Callback NativeManager::callback_;
|
|||||||
ArkUI_NodeHandle xc;
|
ArkUI_NodeHandle xc;
|
||||||
int32_t NativeManager::hasDraw_ = 0;
|
int32_t NativeManager::hasDraw_ = 0;
|
||||||
int32_t NativeManager::hasChangeColor_ = 0;
|
int32_t NativeManager::hasChangeColor_ = 0;
|
||||||
|
static std::map<int64_t, std::shared_ptr<NativeRenderThread>> renderThreadMap;
|
||||||
|
static std::mutex mapMutex;
|
||||||
|
|
||||||
NativeManager::~NativeManager() {
|
NativeManager::~NativeManager() {
|
||||||
OH_LOG_Print(LOG_APP, LOG_ERROR, LOG_PRINT_DOMAIN, "Callback", "~NativeManager");
|
OH_LOG_Print(LOG_APP, LOG_ERROR, LOG_PRINT_DOMAIN, "Callback", "~NativeManager");
|
||||||
nativeXComponentMap_.clear();
|
nativeXComponentMap_.clear();
|
||||||
if (eglcore_ != nullptr) {
|
int64_t id = 0;
|
||||||
delete eglcore_;
|
std::lock_guard<std::mutex> lock(mapMutex);
|
||||||
eglcore_ = nullptr;
|
if (renderThreadMap.find(id) != renderThreadMap.end()) {
|
||||||
|
renderThreadMap[id]->stop();
|
||||||
|
renderThreadMap.erase(id);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (auto iter = pluginManagerMap_.begin(); iter != pluginManagerMap_.end(); ++iter) {
|
for (auto iter = pluginManagerMap_.begin(); iter != pluginManagerMap_.end(); ++iter) {
|
||||||
@ -62,38 +66,38 @@ NativeManager::~NativeManager() {
|
|||||||
pluginManagerMap_.clear();
|
pluginManagerMap_.clear();
|
||||||
}
|
}
|
||||||
// Surface回调事件
|
// Surface回调事件
|
||||||
void OnSurfaceCreatedNative(OH_ArkUI_SurfaceHolder *holder) {
|
//void OnSurfaceCreatedNative(OH_ArkUI_SurfaceHolder *holder) {
|
||||||
auto window = OH_ArkUI_XComponent_GetNativeWindow(holder); // 获取native window
|
// auto window = OH_ArkUI_XComponent_GetNativeWindow(holder); // 获取native window
|
||||||
auto eglCore = reinterpret_cast<EGLCore *>(OH_ArkUI_SurfaceHolder_GetUserData(holder));
|
// auto eglCore = reinterpret_cast<EGLCore *>(OH_ArkUI_SurfaceHolder_GetUserData(holder));
|
||||||
eglCore->EglContextInit(window, 800, 600);
|
// eglCore->EglContextInit(window, 800, 600);
|
||||||
}
|
//}
|
||||||
void OnSurfaceChangedNative(OH_ArkUI_SurfaceHolder *holder, uint64_t width, uint64_t height) {
|
//void OnSurfaceChangedNative(OH_ArkUI_SurfaceHolder *holder, uint64_t width, uint64_t height) {
|
||||||
EGLCore *render = reinterpret_cast<EGLCore *>(OH_ArkUI_SurfaceHolder_GetUserData(holder));
|
// EGLCore *render = reinterpret_cast<EGLCore *>(OH_ArkUI_SurfaceHolder_GetUserData(holder));
|
||||||
render->UpdateSize(width, height); // 设置绘制区域大小
|
// render->UpdateSize(width, height); // 设置绘制区域大小
|
||||||
render->Draw(NativeManager::hasDraw_); // 绘制五角星
|
// //render->Draw(NativeManager::hasDraw_); // 绘制五角星
|
||||||
}
|
//}
|
||||||
void OnSurfaceDestroyedNative(OH_ArkUI_SurfaceHolder *holder) {
|
//void OnSurfaceDestroyedNative(OH_ArkUI_SurfaceHolder *holder) {
|
||||||
OH_LOG_Print(LOG_APP, LOG_ERROR, 0xff00, "onBind", "on destroyed");
|
// OH_LOG_Print(LOG_APP, LOG_ERROR, 0xff00, "onBind", "on destroyed");
|
||||||
EGLCore *render = reinterpret_cast<EGLCore *>(OH_ArkUI_SurfaceHolder_GetUserData(holder));
|
// EGLCore *render = reinterpret_cast<EGLCore *>(OH_ArkUI_SurfaceHolder_GetUserData(holder));
|
||||||
render->Release(); // 销毁eglSurface相关资源
|
// render->Release(); // 销毁eglSurface相关资源
|
||||||
}
|
//}
|
||||||
void OnSurfaceShowNative(OH_ArkUI_SurfaceHolder *holder) {
|
//void OnSurfaceShowNative(OH_ArkUI_SurfaceHolder *holder) {
|
||||||
OH_LOG_Print(LOG_APP, LOG_ERROR, LOG_PRINT_DOMAIN, "onBind", "on surface show");
|
// OH_LOG_Print(LOG_APP, LOG_ERROR, LOG_PRINT_DOMAIN, "onBind", "on surface show");
|
||||||
}
|
//}
|
||||||
void OnSurfaceHideNative(OH_ArkUI_SurfaceHolder *holder) {
|
//void OnSurfaceHideNative(OH_ArkUI_SurfaceHolder *holder) {
|
||||||
OH_LOG_Print(LOG_APP, LOG_ERROR, LOG_PRINT_DOMAIN, "onBind", "on surface hide");
|
// OH_LOG_Print(LOG_APP, LOG_ERROR, LOG_PRINT_DOMAIN, "onBind", "on surface hide");
|
||||||
}
|
//}
|
||||||
void OnFrameCallbackNative(ArkUI_NodeHandle node, uint64_t timestamp, uint64_t targetTimestamp) {
|
//void OnFrameCallbackNative(ArkUI_NodeHandle node, uint64_t timestamp, uint64_t targetTimestamp) {
|
||||||
if (!NativeManager::surfaceHolderMap_.count(node)) {
|
// if (!NativeManager::surfaceHolderMap_.count(node)) {
|
||||||
return;
|
// return;
|
||||||
}
|
// }
|
||||||
static uint64_t count = 0;
|
// static uint64_t count = 0;
|
||||||
count++;
|
// count++;
|
||||||
// 在头文件plugin_manager.h中定义,FRAME_COUNT的值为50
|
// // 在头文件plugin_manager.h中定义,FRAME_COUNT的值为50
|
||||||
if (count % FRAME_COUNT == 0) {
|
// if (count % FRAME_COUNT == 0) {
|
||||||
OH_LOG_Print(LOG_APP, LOG_ERROR, LOG_PRINT_DOMAIN, "onBind", "OnFrameCallback count = %{public}ld", count);
|
// OH_LOG_Print(LOG_APP, LOG_ERROR, LOG_PRINT_DOMAIN, "onBind", "OnFrameCallback count = %{public}ld", count);
|
||||||
}
|
// }
|
||||||
}
|
//}
|
||||||
void OnSurfaceCreatedCB(OH_NativeXComponent *component, void *window) {
|
void OnSurfaceCreatedCB(OH_NativeXComponent *component, void *window) {
|
||||||
// [StartExclude plugin_on_surface_created]
|
// [StartExclude plugin_on_surface_created]
|
||||||
OH_LOG_Print(LOG_APP, LOG_ERROR, LOG_PRINT_DOMAIN, "XComponent_Native", "OnSurfaceCreatedCB");
|
OH_LOG_Print(LOG_APP, LOG_ERROR, LOG_PRINT_DOMAIN, "XComponent_Native", "OnSurfaceCreatedCB");
|
||||||
@ -144,79 +148,38 @@ void OnSurfaceDestroyedCB(OH_NativeXComponent *component, void *window) {
|
|||||||
auto *pluginManger = NativeManager::GetInstance();
|
auto *pluginManger = NativeManager::GetInstance();
|
||||||
pluginManger->OnSurfaceDestroyed(component, window);
|
pluginManger->OnSurfaceDestroyed(component, window);
|
||||||
}
|
}
|
||||||
void DispatchTouchEventCB(OH_NativeXComponent *component, void *window) {
|
|
||||||
// [StartExclude plugin_dispatch_touch_event]
|
|
||||||
OH_LOG_Print(LOG_APP, LOG_ERROR, LOG_PRINT_DOMAIN, "Callback", "DispatchTouchEventCB");
|
|
||||||
int32_t ret;
|
|
||||||
char idStr[OH_XCOMPONENT_ID_LEN_MAX + 1] = {};
|
|
||||||
uint64_t idSize = OH_XCOMPONENT_ID_LEN_MAX + 1;
|
|
||||||
ret = OH_NativeXComponent_GetXComponentId(component, idStr, &idSize);
|
|
||||||
if (ret != OH_NATIVEXCOMPONENT_RESULT_SUCCESS) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
std::string id(idStr);
|
|
||||||
// [EndExclude plugin_dispatch_touch_event]
|
|
||||||
auto *pluginManger = NativeManager::GetInstance();
|
|
||||||
pluginManger->DispatchTouchEvent(component, window);
|
|
||||||
}
|
|
||||||
//NativeManager回调
|
//NativeManager回调
|
||||||
void NativeManager::OnSurfaceCreated(OH_NativeXComponent *component, void *window) {
|
void NativeManager::OnSurfaceCreated(OH_NativeXComponent *component, void *window) {
|
||||||
OH_LOG_Print(LOG_APP, LOG_ERROR, LOG_PRINT_DOMAIN, "XComponent_Native", "PluginManager::OnSurfaceCreated");
|
OH_LOG_Print(LOG_APP, LOG_ERROR, LOG_PRINT_DOMAIN, "XComponent_Native", "PluginManager::OnSurfaceCreated");
|
||||||
int32_t ret;
|
OH_NativeXComponent_GetXComponentSize(component, window, &width_, &height_);
|
||||||
char idStr[OH_XCOMPONENT_ID_LEN_MAX + 1] = {};
|
int64_t id = 0;
|
||||||
uint64_t idSize = OH_XCOMPONENT_ID_LEN_MAX + 1;
|
std::lock_guard<std::mutex> lock(mapMutex);
|
||||||
ret = OH_NativeXComponent_GetXComponentId(component, idStr, &idSize);
|
if (renderThreadMap.find(id) == renderThreadMap.end()) {
|
||||||
ret = OH_NativeXComponent_GetXComponentSize(component, window, &width_, &height_);
|
auto renderThread = std::make_shared<NativeRenderThread>();
|
||||||
if (ret == OH_NATIVEXCOMPONENT_RESULT_SUCCESS) {
|
renderThreadMap[id] = renderThread;
|
||||||
eglcore_->EglContextInit(window, width_, height_);
|
renderThread->start(reinterpret_cast<OHNativeWindow*>(window));
|
||||||
eglcore_->Background();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
void NativeManager::OnSurfaceDestroyed(OH_NativeXComponent *component, void *window) {
|
void NativeManager::OnSurfaceDestroyed(OH_NativeXComponent *component, void *window) {
|
||||||
OH_LOG_Print(LOG_APP, LOG_ERROR, LOG_PRINT_DOMAIN, "XComponent_Native", "PluginManager::OnSurfaceDestroyed");
|
OH_LOG_Print(LOG_APP, LOG_ERROR, LOG_PRINT_DOMAIN, "XComponent_Native", "PluginManager::OnSurfaceDestroyed");
|
||||||
}
|
int64_t id = 0;
|
||||||
void NativeManager::DispatchTouchEvent(OH_NativeXComponent *component, void *window) {
|
{
|
||||||
int32_t ret = OH_NativeXComponent_GetTouchEvent(component, window, &touchEvent_);
|
std::lock_guard<std::mutex> lock(mapMutex);
|
||||||
if (ret == OH_NATIVEXCOMPONENT_RESULT_SUCCESS) {
|
if (renderThreadMap.find(id) != renderThreadMap.end()) {
|
||||||
float tiltX = 2.2;
|
renderThreadMap[id]->stop();
|
||||||
float tiltY = 2.2;
|
renderThreadMap.erase(id);
|
||||||
OH_NativeXComponent_TouchPointToolType toolType =
|
|
||||||
OH_NativeXComponent_TouchPointToolType::OH_NATIVEXCOMPONENT_TOOL_TYPE_LENS;
|
|
||||||
OH_NativeXComponent_GetTouchPointToolType(component, 0, &toolType);
|
|
||||||
OH_NativeXComponent_GetTouchPointTiltX(component, 0, &tiltX);
|
|
||||||
OH_NativeXComponent_GetTouchPointTiltY(component, 0, &tiltY);
|
|
||||||
OH_LOG_Print(LOG_APP, LOG_ERROR, LOG_PRINT_DOMAIN, "XComponent_Native",
|
|
||||||
"Touch Info : x=%{public}f, y=%{public}f screenx=%{public}f, screeny=%{public}f,"
|
|
||||||
"type=%{public}d, force=%{public}f, tiltX=%{public}f, tiltY=%{public}f, toolType=%{public}d",
|
|
||||||
touchEvent_.x, touchEvent_.y, touchEvent_.screenX, touchEvent_.screenY, touchEvent_.type,
|
|
||||||
touchEvent_.force, tiltX, tiltY, toolType);
|
|
||||||
if (touchEvent_.type == OH_NativeXComponent_TouchEventType::OH_NATIVEXCOMPONENT_UP) {
|
|
||||||
eglcore_->ChangeColor(hasChangeColor_);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
OH_LOG_Print(LOG_APP, LOG_ERROR, LOG_PRINT_DOMAIN, "XComponent_Native", "touch fail");
|
|
||||||
}
|
|
||||||
|
|
||||||
int32_t size = 0;
|
|
||||||
OH_NativeXComponent_HistoricalPoint *points = nullptr;
|
|
||||||
|
|
||||||
if (OH_NativeXComponent_GetHistoricalPoints(component, window, &size, &points) ==
|
|
||||||
OH_NATIVEXCOMPONENT_RESULT_SUCCESS) {
|
|
||||||
OH_LOG_Print(LOG_APP, LOG_INFO, LOG_PRINT_DOMAIN, "XComponent_Native", "HistoricalPoints size=%{public}d",
|
|
||||||
size);
|
|
||||||
for (auto i = 0; i < size; i++) {
|
|
||||||
auto point = points[i];
|
|
||||||
OH_LOG_Print(LOG_APP, LOG_INFO, LOG_PRINT_DOMAIN, "XComponent_Native",
|
|
||||||
"HistoricalPoint %{public}d Info : id=%{public}d, x=%{public}f, y=%{public}f, "
|
|
||||||
"type=%{public}d, timeStamp=%{public}lld, sourceTool=%{public}d",
|
|
||||||
i, point.id, point.x, point.y, point.type, point.timeStamp, point.sourceTool);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
void NativeManager::OnSurfaceChanged(OH_NativeXComponent *component, void *window) {
|
void NativeManager::OnSurfaceChanged(OH_NativeXComponent *component, void *window) {
|
||||||
int32_t ret = OH_NativeXComponent_GetXComponentSize(component, window, &width_, &height_);
|
OH_NativeXComponent_GetXComponentSize(component, window, &width_, &height_);
|
||||||
OH_LOG_Print(LOG_APP, LOG_ERROR, LOG_PRINT_DOMAIN, "XComponent_Native",
|
int64_t id = 0;
|
||||||
"OnSurfaceChanged ret=%{public}d width=%{public}lu, height=%{public}lu", ret, width_, height_);
|
{
|
||||||
|
std::lock_guard<std::mutex> lock(mapMutex);
|
||||||
|
if (renderThreadMap.find(id) != renderThreadMap.end()) {
|
||||||
|
renderThreadMap[id]->resizeWindow(width_, height_);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
void onEvent(ArkUI_NodeEvent *event) {
|
void onEvent(ArkUI_NodeEvent *event) {
|
||||||
auto eventType = OH_ArkUI_NodeEvent_GetEventType(event); // 获取组件事件类型
|
auto eventType = OH_ArkUI_NodeEvent_GetEventType(event); // 获取组件事件类型
|
||||||
@ -225,7 +188,6 @@ void onEvent(ArkUI_NodeEvent *event) {
|
|||||||
ArkUI_NodeHandle handle = OH_ArkUI_NodeEvent_GetNodeHandle(event); // 获取触发该事件的组件对象
|
ArkUI_NodeHandle handle = OH_ArkUI_NodeEvent_GetNodeHandle(event); // 获取触发该事件的组件对象
|
||||||
auto holder = NativeManager::surfaceHolderMap_[handle];
|
auto holder = NativeManager::surfaceHolderMap_[handle];
|
||||||
EGLCore *render = reinterpret_cast<EGLCore *>(OH_ArkUI_SurfaceHolder_GetUserData(holder));
|
EGLCore *render = reinterpret_cast<EGLCore *>(OH_ArkUI_SurfaceHolder_GetUserData(holder));
|
||||||
render->Draw(NativeManager::hasDraw_); // 绘制五角星
|
|
||||||
OH_LOG_Print(LOG_APP, LOG_ERROR, LOG_PRINT_DOMAIN, "onBind", "on touch");
|
OH_LOG_Print(LOG_APP, LOG_ERROR, LOG_PRINT_DOMAIN, "onBind", "on touch");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -237,35 +199,11 @@ static std::string value2String(napi_env env, napi_value value) {
|
|||||||
napi_get_value_string_utf8(env, value, &valueString[0], stringSize + 1, &stringSize);
|
napi_get_value_string_utf8(env, value, &valueString[0], stringSize + 1, &stringSize);
|
||||||
return valueString;
|
return valueString;
|
||||||
}
|
}
|
||||||
napi_value NativeManager::NapiDrawPattern(napi_env env, napi_callback_info info) {
|
|
||||||
// [StartExclude plugin_draw_pattern]
|
|
||||||
OH_LOG_Print(LOG_APP, LOG_INFO, LOG_PRINT_DOMAIN, "NativeManager", "NapiDrawPattern");
|
|
||||||
if ((env == nullptr) || (info == nullptr)) {
|
|
||||||
OH_LOG_Print(LOG_APP, LOG_ERROR, LOG_PRINT_DOMAIN, "NativeManager", "NapiDrawPattern: env or info is null");
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
// [EndExclude plugin_draw_pattern]
|
|
||||||
// 获取环境变量参数
|
|
||||||
napi_value thisArg;
|
|
||||||
if (napi_get_cb_info(env, info, nullptr, nullptr, &thisArg, nullptr) != napi_ok) {
|
|
||||||
OH_LOG_Print(LOG_APP, LOG_ERROR, LOG_PRINT_DOMAIN, "NativeManager", "NapiDrawPattern: napi_get_cb_info fail");
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
auto *pluginManger = NativeManager::GetInstance();
|
|
||||||
// 调用绘制方法
|
|
||||||
pluginManger->eglcore_->Draw(hasDraw_);
|
|
||||||
OH_LOG_Print(LOG_APP, LOG_INFO, LOG_PRINT_DOMAIN, "NativeManager", "render->eglCore_->Draw() executed");
|
|
||||||
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
// XComponent回调事件
|
// XComponent回调事件
|
||||||
NativeManager::NativeManager() {
|
NativeManager::NativeManager() {
|
||||||
eglcore_ = new EGLCore();
|
|
||||||
callback_.OnSurfaceCreated = OnSurfaceCreatedCB;
|
callback_.OnSurfaceCreated = OnSurfaceCreatedCB;
|
||||||
callback_.OnSurfaceChanged = OnSurfaceChangedCB;
|
callback_.OnSurfaceChanged = OnSurfaceChangedCB;
|
||||||
callback_.OnSurfaceDestroyed = OnSurfaceDestroyedCB;
|
callback_.OnSurfaceDestroyed = OnSurfaceDestroyedCB;
|
||||||
callback_.DispatchTouchEvent = DispatchTouchEventCB;
|
|
||||||
}
|
}
|
||||||
// 创建节点组件
|
// 创建节点组件
|
||||||
ArkUI_NodeHandle CreateNodeHandle(const std::string &tag) {
|
ArkUI_NodeHandle CreateNodeHandle(const std::string &tag) {
|
||||||
@ -419,5 +357,18 @@ napi_value NativeManager::SetNeedSoftKeyboard(napi_env env, napi_callback_info i
|
|||||||
OH_ArkUI_XComponent_SetNeedSoftKeyboard(node, needSoftKeyboard); // 设置是否需要软键盘
|
OH_ArkUI_XComponent_SetNeedSoftKeyboard(node, needSoftKeyboard); // 设置是否需要软键盘
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
napi_value NativeManager::NapiLoadModel(napi_env env, napi_callback_info info) {
|
||||||
|
size_t argc = 1;
|
||||||
|
napi_value args[1];
|
||||||
|
napi_get_cb_info(env, info, &argc, args, nullptr, nullptr);
|
||||||
|
std::string path = value2String(env, args[0]);
|
||||||
|
int64_t id = 0;
|
||||||
|
{
|
||||||
|
std::lock_guard<std::mutex> lock(mapMutex);
|
||||||
|
if (renderThreadMap.find(id) != renderThreadMap.end()) {
|
||||||
|
renderThreadMap[id]->loadModel(std::string(path));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
} // namespace NativeOpenCAX
|
} // namespace NativeOpenCAX
|
||||||
|
|||||||
@ -25,7 +25,7 @@
|
|||||||
#include "EGLCore.h"
|
#include "EGLCore.h"
|
||||||
#include "arkui/native_node.h"
|
#include "arkui/native_node.h"
|
||||||
#include "arkui/native_node_napi.h"
|
#include "arkui/native_node_napi.h"
|
||||||
|
#include "NativeRenderThread.h"
|
||||||
|
|
||||||
namespace NativeOpenCAX {
|
namespace NativeOpenCAX {
|
||||||
|
|
||||||
@ -47,9 +47,9 @@ public:
|
|||||||
return &NativeManager::pluginManager_;
|
return &NativeManager::pluginManager_;
|
||||||
}
|
}
|
||||||
static napi_value createNativeNode(napi_env env, napi_callback_info info);
|
static napi_value createNativeNode(napi_env env, napi_callback_info info);
|
||||||
static napi_value NapiDrawPattern(napi_env env, napi_callback_info info);
|
|
||||||
static napi_value SetFrameRate(napi_env env, napi_callback_info info);
|
static napi_value SetFrameRate(napi_env env, napi_callback_info info);
|
||||||
static napi_value SetNeedSoftKeyboard(napi_env env, napi_callback_info info);
|
static napi_value SetNeedSoftKeyboard(napi_env env, napi_callback_info info);
|
||||||
|
static napi_value NapiLoadModel(napi_env env, napi_callback_info info);
|
||||||
// CApi XComponent
|
// CApi XComponent
|
||||||
void OnSurfaceChanged(OH_NativeXComponent* component, void* window);
|
void OnSurfaceChanged(OH_NativeXComponent* component, void* window);
|
||||||
void OnSurfaceDestroyed(OH_NativeXComponent* component, void* window);
|
void OnSurfaceDestroyed(OH_NativeXComponent* component, void* window);
|
||||||
@ -61,10 +61,10 @@ private:
|
|||||||
std::unordered_map<std::string, NativeManager*> pluginManagerMap_;
|
std::unordered_map<std::string, NativeManager*> pluginManagerMap_;
|
||||||
public:
|
public:
|
||||||
// [StartExclude plugin_manager_h_part]
|
// [StartExclude plugin_manager_h_part]
|
||||||
EGLCore *eglcore_;
|
|
||||||
uint64_t width_;
|
uint64_t width_;
|
||||||
uint64_t height_;
|
uint64_t height_;
|
||||||
OH_NativeXComponent_TouchEvent touchEvent_;
|
OH_NativeXComponent_TouchEvent touchEvent_;
|
||||||
|
std::string modelPath_;
|
||||||
static int32_t hasDraw_;
|
static int32_t hasDraw_;
|
||||||
static int32_t hasChangeColor_;
|
static int32_t hasChangeColor_;
|
||||||
static std::unordered_map<std::string, ArkUI_NodeHandle> nodeHandleMap_;
|
static std::unordered_map<std::string, ArkUI_NodeHandle> nodeHandleMap_;
|
||||||
|
|||||||
279
entry/src/main/cpp/NativeEGLOCCT/NativeRender.cpp
Normal file
279
entry/src/main/cpp/NativeEGLOCCT/NativeRender.cpp
Normal file
@ -0,0 +1,279 @@
|
|||||||
|
#include "NativeRender.h"
|
||||||
|
#include <cstdio>
|
||||||
|
#include <cmath>
|
||||||
|
#include <OSD_Environment.hxx>
|
||||||
|
#include <AIS_InteractiveObject.hxx>
|
||||||
|
#include <Prs3d_Drawer.hxx>
|
||||||
|
#include <Prs3d_ShadingAspect.hxx>
|
||||||
|
#include <Graphic3d_MaterialAspect.hxx>
|
||||||
|
#include <Graphic3d_NameOfMaterial.hxx>
|
||||||
|
#include <BRepPrimAPI_MakeBox.hxx>
|
||||||
|
#include <BRepPrimAPI_MakeSphere.hxx>
|
||||||
|
#include <BRepPrimAPI_MakeCylinder.hxx>
|
||||||
|
#include <Graphic3d_TextureEnv.hxx>
|
||||||
|
#include <V3d_TypeOfOrientation.hxx>
|
||||||
|
#include <Aspect_TypeOfTriedronPosition.hxx>
|
||||||
|
|
||||||
|
namespace NativeOpenCAX {
|
||||||
|
|
||||||
|
NativeRender::NativeRender()
|
||||||
|
: rotationX_(0.0f),
|
||||||
|
rotationY_(0.0f),
|
||||||
|
zoomLevel_(1.0f),
|
||||||
|
width_(0),
|
||||||
|
height_(0),
|
||||||
|
clearColor_(Quantity_NOC_BLACK),
|
||||||
|
translationX_(0.0f),
|
||||||
|
translationY_(0.0f)
|
||||||
|
{
|
||||||
|
setupViewer();
|
||||||
|
setupContext();
|
||||||
|
setupView();
|
||||||
|
}
|
||||||
|
|
||||||
|
NativeRender::~NativeRender() {
|
||||||
|
shapes_.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool NativeRender::init(int width, int height) {
|
||||||
|
width_ = width;
|
||||||
|
height_ = height;
|
||||||
|
if (view_.IsNull()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
view_->SetBackgroundColor(clearColor_);
|
||||||
|
view_->MustBeResized();
|
||||||
|
view_->Redraw();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void NativeRender::setupViewer() {
|
||||||
|
Handle(Aspect_DisplayConnection) displayConnection;
|
||||||
|
|
||||||
|
// 创建图形驱动
|
||||||
|
static Handle(OpenGl_GraphicDriver) graphicDriver;
|
||||||
|
if (graphicDriver.IsNull()) {
|
||||||
|
graphicDriver = new OpenGl_GraphicDriver(displayConnection, Standard_False);
|
||||||
|
graphicDriver->ChangeOptions().buffersNoSwap = Standard_True;
|
||||||
|
}
|
||||||
|
graphicDriver_ = graphicDriver;
|
||||||
|
|
||||||
|
// 创建V3d_Viewer
|
||||||
|
viewer_ = new V3d_Viewer(graphicDriver_);
|
||||||
|
viewer_->SetDefaultLights();
|
||||||
|
viewer_->SetLightOn();
|
||||||
|
}
|
||||||
|
|
||||||
|
void NativeRender::setupContext() {
|
||||||
|
context_ = new AIS_InteractiveContext(viewer_);
|
||||||
|
context_->SetDisplayMode(AIS_Shaded, Standard_False); // 默认使用着色模式
|
||||||
|
}
|
||||||
|
|
||||||
|
void NativeRender::setupView() {
|
||||||
|
view_ = viewer_->CreateView();
|
||||||
|
|
||||||
|
// 设置渲染参数
|
||||||
|
view_->ChangeRenderingParams().Method = Graphic3d_RM_RASTERIZATION;
|
||||||
|
view_->ChangeRenderingParams().IsShadowEnabled = Standard_False;
|
||||||
|
view_->ChangeRenderingParams().IsReflectionEnabled = Standard_False;
|
||||||
|
view_->ChangeRenderingParams().IsAntialiasingEnabled = Standard_True;
|
||||||
|
view_->ChangeRenderingParams().Resolution = 2;
|
||||||
|
|
||||||
|
// 设置背景渐变
|
||||||
|
view_->SetBgGradientColors(
|
||||||
|
Quantity_Color(Quantity_NOC_GRAY),
|
||||||
|
Quantity_Color(Quantity_NOC_BLACK),
|
||||||
|
Aspect_GFM_VER, // 垂直渐变
|
||||||
|
Standard_False
|
||||||
|
);
|
||||||
|
|
||||||
|
// 设置默认相机位置
|
||||||
|
view_->SetProj(V3d_XposYnegZpos);
|
||||||
|
|
||||||
|
// 设置相机参数
|
||||||
|
Handle(Graphic3d_Camera) camera = view_->Camera();
|
||||||
|
camera->SetFOVy(45.0); // 使用正确的FOV设置API
|
||||||
|
camera->SetZRange(1.0, 10000.0);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool NativeRender::loadModel(const std::string& filePath) {
|
||||||
|
// 清除现有模型
|
||||||
|
for (auto& shape : shapes_) {
|
||||||
|
context_->Remove(shape, Standard_False);
|
||||||
|
}
|
||||||
|
shapes_.clear();
|
||||||
|
|
||||||
|
// 加载STEP文件
|
||||||
|
STEPControl_Reader reader;
|
||||||
|
IFSelect_ReturnStatus status = reader.ReadFile(filePath.c_str());
|
||||||
|
if (status != IFSelect_RetDone) {
|
||||||
|
printf("Error: Failed to read STEP file: %s\n", filePath.c_str());
|
||||||
|
loadDefaultModel();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 将文件内容转换为OCCT形状
|
||||||
|
reader.TransferRoots();
|
||||||
|
int numShapes = reader.NbShapes();
|
||||||
|
if (numShapes <= 0) {
|
||||||
|
printf("Error: No shapes found in STEP file\n");
|
||||||
|
loadDefaultModel();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 加载所有形状
|
||||||
|
for (Standard_Integer i = 1; i <= numShapes; i++) {
|
||||||
|
TopoDS_Shape shape = reader.Shape(i);
|
||||||
|
if (!shape.IsNull()) {
|
||||||
|
Handle(AIS_Shape) aisShape = new AIS_Shape(shape);
|
||||||
|
|
||||||
|
// 设置材质
|
||||||
|
Handle(Prs3d_Drawer) drawer = aisShape->Attributes();
|
||||||
|
Handle(Prs3d_ShadingAspect) shadingAspect = new Prs3d_ShadingAspect();
|
||||||
|
|
||||||
|
// 随机颜色
|
||||||
|
int colorIndex = i % 7;
|
||||||
|
Quantity_Color color;
|
||||||
|
switch (colorIndex) {
|
||||||
|
case 0: color = Quantity_NOC_RED; break;
|
||||||
|
case 1: color = Quantity_NOC_GREEN; break;
|
||||||
|
case 2: color = Quantity_NOC_BLUE1; break;
|
||||||
|
case 3: color = Quantity_NOC_YELLOW; break;
|
||||||
|
case 4: color = Quantity_NOC_MAGENTA1; break;
|
||||||
|
case 5: color = Quantity_NOC_CYAN1; break;
|
||||||
|
case 6: color = Quantity_NOC_ORANGE; break;
|
||||||
|
default: color = Quantity_NOC_WHITE;
|
||||||
|
}
|
||||||
|
|
||||||
|
shadingAspect->SetColor(color);
|
||||||
|
shadingAspect->SetMaterial(Graphic3d_NOM_PLASTIC);
|
||||||
|
drawer->SetShadingAspect(shadingAspect);
|
||||||
|
|
||||||
|
context_->Display(aisShape, Standard_True);
|
||||||
|
shapes_.push_back(aisShape);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 调整相机到合适位置
|
||||||
|
view_->FitAll(0.05, Standard_True);
|
||||||
|
view_->ZFitAll();
|
||||||
|
printf("Successfully loaded STEP file with %d shapes\n", numShapes);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void NativeRender::loadDefaultModel() {
|
||||||
|
// 创建一个默认的3D立方体
|
||||||
|
TopoDS_Shape box = BRepPrimAPI_MakeBox(10.0, 10.0, 10.0).Shape();
|
||||||
|
Handle(AIS_Shape) aisBox = new AIS_Shape(box);
|
||||||
|
|
||||||
|
// 设置材质和颜色
|
||||||
|
Handle(Prs3d_Drawer) drawer = aisBox->Attributes();
|
||||||
|
Handle(Prs3d_ShadingAspect) shadingAspect = new Prs3d_ShadingAspect();
|
||||||
|
shadingAspect->SetColor(Quantity_NOC_RED);
|
||||||
|
shadingAspect->SetMaterial(Graphic3d_NOM_PLASTIC);
|
||||||
|
drawer->SetShadingAspect(shadingAspect);
|
||||||
|
|
||||||
|
context_->Display(aisBox, Standard_True);
|
||||||
|
shapes_.push_back(aisBox);
|
||||||
|
|
||||||
|
// 创建一个球体
|
||||||
|
TopoDS_Shape sphere = BRepPrimAPI_MakeSphere(gp_Pnt(20.0, 0.0, 0.0), 5.0).Shape();
|
||||||
|
Handle(AIS_Shape) aisSphere = new AIS_Shape(sphere);
|
||||||
|
shadingAspect = new Prs3d_ShadingAspect();
|
||||||
|
shadingAspect->SetColor(Quantity_NOC_BLUE1);
|
||||||
|
shadingAspect->SetMaterial(Graphic3d_NOM_PLASTIC);
|
||||||
|
aisSphere->Attributes()->SetShadingAspect(shadingAspect);
|
||||||
|
context_->Display(aisSphere, Standard_True);
|
||||||
|
shapes_.push_back(aisSphere);
|
||||||
|
|
||||||
|
// 创建一个圆柱体
|
||||||
|
TopoDS_Shape cylinder = BRepPrimAPI_MakeCylinder(3.0, 15.0).Shape();
|
||||||
|
Handle(AIS_Shape) aisCylinder = new AIS_Shape(cylinder);
|
||||||
|
shadingAspect = new Prs3d_ShadingAspect();
|
||||||
|
shadingAspect->SetColor(Quantity_NOC_GREEN);
|
||||||
|
shadingAspect->SetMaterial(Graphic3d_NOM_PLASTIC);
|
||||||
|
aisCylinder->Attributes()->SetShadingAspect(shadingAspect);
|
||||||
|
|
||||||
|
gp_Trsf transform;
|
||||||
|
transform.SetTranslation(gp_Vec(-15.0, -15.0, 0.0));
|
||||||
|
aisCylinder->SetLocalTransformation(transform);
|
||||||
|
|
||||||
|
context_->Display(aisCylinder, Standard_True);
|
||||||
|
shapes_.push_back(aisCylinder);
|
||||||
|
|
||||||
|
// 调整相机
|
||||||
|
view_->FitAll(0.05, Standard_True);
|
||||||
|
view_->ZFitAll();
|
||||||
|
printf("Loaded default model (cube, sphere, cylinder)\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
//setTranslation
|
||||||
|
void NativeRender::setTranslation(float x, float y) {
|
||||||
|
translationX_ = x;
|
||||||
|
translationY_ = y;
|
||||||
|
}
|
||||||
|
|
||||||
|
void NativeRender::render() {
|
||||||
|
if (view_.IsNull()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 应用旋转
|
||||||
|
Handle(Graphic3d_Camera) camera = view_->Camera();
|
||||||
|
// 计算旋转
|
||||||
|
gp_Quaternion rotation;
|
||||||
|
rotation.SetEulerAngles(gp_EulerSequence::gp_Extrinsic_XYZ,
|
||||||
|
rotationX_ * M_PI / 180.0,
|
||||||
|
rotationY_ * M_PI / 180.0,
|
||||||
|
0.0);
|
||||||
|
|
||||||
|
// 计算相机位置
|
||||||
|
gp_Dir camDir(0.0, 1.0, 0.0);
|
||||||
|
gp_Vec camVec = rotation * gp_Vec(camDir);
|
||||||
|
gp_Pnt camPos = gp_Pnt(0.0, 0.0, 0.0).Translated(camVec.Reversed() * 50.0 * zoomLevel_);
|
||||||
|
|
||||||
|
// 设置相机参数
|
||||||
|
camera->SetEye(camPos);
|
||||||
|
camera->SetCenter(gp_Pnt(translationX_, translationY_, 0.0));
|
||||||
|
camera->SetUp(gp_Dir(0.0, 0.0, 1.0));
|
||||||
|
// 执行渲染
|
||||||
|
view_->Redraw();
|
||||||
|
}
|
||||||
|
|
||||||
|
void NativeRender::resize(int width, int height) {
|
||||||
|
width_ = width;
|
||||||
|
height_ = height;
|
||||||
|
if (!view_.IsNull() && nativeWindow_ != nullptr) {
|
||||||
|
view_->SetWindow(nativeWindow_);
|
||||||
|
view_->MustBeResized();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void NativeRender::setRotation(float xAngle, float yAngle) {
|
||||||
|
rotationX_ = xAngle;
|
||||||
|
rotationY_ = yAngle;
|
||||||
|
}
|
||||||
|
|
||||||
|
void NativeRender::setZoomLevel(float zoom) {
|
||||||
|
zoomLevel_ = std::max(0.1f, std::min(zoom, 5.0f)); // 限制缩放范围
|
||||||
|
}
|
||||||
|
|
||||||
|
void NativeRender::resetView() {
|
||||||
|
rotationX_ = 0.0f;
|
||||||
|
rotationY_ = 0.0f;
|
||||||
|
zoomLevel_ = 1.0f;
|
||||||
|
|
||||||
|
if (!view_.IsNull()) {
|
||||||
|
view_->SetProj(V3d_XposYnegZpos);
|
||||||
|
view_->FitAll(0.05, Standard_False);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void NativeRender::setClearColor(float r, float g, float b, float a) {
|
||||||
|
clearColor_ = Quantity_Color(r, g, b, Quantity_TOC_RGB);
|
||||||
|
if (!view_.IsNull()) {
|
||||||
|
view_->SetBackgroundColor(clearColor_);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace NativeRenderer
|
||||||
64
entry/src/main/cpp/NativeEGLOCCT/NativeRender.h
Normal file
64
entry/src/main/cpp/NativeEGLOCCT/NativeRender.h
Normal file
@ -0,0 +1,64 @@
|
|||||||
|
#ifndef NATIVE_RENDER_H
|
||||||
|
#define NATIVE_RENDER_H
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
#include <vector>
|
||||||
|
#include <Standard_Handle.hxx>
|
||||||
|
#include <AIS_InteractiveContext.hxx>
|
||||||
|
#include <V3d_View.hxx>
|
||||||
|
#include <V3d_Viewer.hxx>
|
||||||
|
#include <OpenGl_GraphicDriver.hxx>
|
||||||
|
#include <AIS_Shape.hxx>
|
||||||
|
#include <STEPControl_Reader.hxx>
|
||||||
|
#include <TopoDS_Shape.hxx>
|
||||||
|
#include <Graphic3d_GraphicDriver.hxx>
|
||||||
|
#include <Aspect_DisplayConnection.hxx>
|
||||||
|
#include <Message.hxx>
|
||||||
|
#include <Quantity_Color.hxx>
|
||||||
|
#include <gp_Quaternion.hxx>
|
||||||
|
#include <gp_EulerSequence.hxx>
|
||||||
|
|
||||||
|
class Aspect_Window;
|
||||||
|
class gp_Quaternion;
|
||||||
|
class Graphic3d_Camera;
|
||||||
|
|
||||||
|
namespace NativeOpenCAX {
|
||||||
|
class NativeRender {
|
||||||
|
public:
|
||||||
|
NativeRender();
|
||||||
|
~NativeRender();
|
||||||
|
|
||||||
|
bool init(int width, int height);
|
||||||
|
bool loadModel(const std::string& filePath);
|
||||||
|
void render();
|
||||||
|
void resize(int width, int height);
|
||||||
|
void setRotation(float xAngle, float yAngle);
|
||||||
|
void resetView();
|
||||||
|
void setClearColor(float r, float g, float b, float a);
|
||||||
|
void setZoomLevel(float zoom);
|
||||||
|
void setTranslation(float x, float y);
|
||||||
|
|
||||||
|
private:
|
||||||
|
void setupViewer();
|
||||||
|
void setupContext();
|
||||||
|
void setupView();
|
||||||
|
void loadDefaultModel();
|
||||||
|
|
||||||
|
Handle(OpenGl_GraphicDriver) graphicDriver_;
|
||||||
|
Handle(V3d_Viewer) viewer_;
|
||||||
|
Handle(V3d_View) view_;
|
||||||
|
Handle(AIS_InteractiveContext) context_;
|
||||||
|
std::vector<Handle(AIS_Shape)> shapes_;
|
||||||
|
|
||||||
|
float rotationX_;
|
||||||
|
float rotationY_;
|
||||||
|
float zoomLevel_;
|
||||||
|
int width_;
|
||||||
|
int height_;
|
||||||
|
float translationX_;
|
||||||
|
float translationY_;
|
||||||
|
Quantity_Color clearColor_;
|
||||||
|
Aspect_Window* nativeWindow_;
|
||||||
|
};
|
||||||
|
} // namespace NativeRender
|
||||||
|
#endif // NATIVE_RENDER_H
|
||||||
190
entry/src/main/cpp/NativeEGLOCCT/NativeRenderThread.cpp
Normal file
190
entry/src/main/cpp/NativeEGLOCCT/NativeRenderThread.cpp
Normal file
@ -0,0 +1,190 @@
|
|||||||
|
#include "NativeRenderThread.h"
|
||||||
|
#include <cstdio>
|
||||||
|
#include <unistd.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(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();
|
||||||
|
|
||||||
|
// 调用渲染完成回调
|
||||||
|
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
|
||||||
73
entry/src/main/cpp/NativeEGLOCCT/NativeRenderThread.h
Normal file
73
entry/src/main/cpp/NativeEGLOCCT/NativeRenderThread.h
Normal file
@ -0,0 +1,73 @@
|
|||||||
|
#ifndef NATIVE_RENDER_THREAD_H
|
||||||
|
#define NATIVE_RENDER_THREAD_H
|
||||||
|
#include <thread>
|
||||||
|
#include <atomic>
|
||||||
|
#include <mutex>
|
||||||
|
#include <condition_variable>
|
||||||
|
#include <queue>
|
||||||
|
#include <functional>
|
||||||
|
|
||||||
|
#include "EGLCore.h"
|
||||||
|
#include "NativeRender.h"
|
||||||
|
|
||||||
|
namespace NativeOpenCAX {
|
||||||
|
|
||||||
|
class NativeRenderThread {
|
||||||
|
public:
|
||||||
|
NativeRenderThread();
|
||||||
|
~NativeRenderThread();
|
||||||
|
|
||||||
|
bool start(OHNativeWindow* window);
|
||||||
|
void stop();
|
||||||
|
|
||||||
|
void loadModel(const std::string& filePath);
|
||||||
|
void setRotation(float xAngle, float yAngle);
|
||||||
|
void setTranslation(float x, float y);
|
||||||
|
void resetView();
|
||||||
|
void setClearColor(float r, float g, float b, float a);
|
||||||
|
void resizeWindow(int width, int height);
|
||||||
|
|
||||||
|
using Callback = std::function<void()>;
|
||||||
|
void registerRenderCompleteCallback(Callback callback);
|
||||||
|
|
||||||
|
private:
|
||||||
|
void renderLoop();
|
||||||
|
|
||||||
|
std::thread renderThread_;
|
||||||
|
std::atomic<bool> isRunning_;
|
||||||
|
|
||||||
|
OHNativeWindow* nativeWindow_;
|
||||||
|
EGLCore eglCore_;
|
||||||
|
NativeRender renderer_;
|
||||||
|
|
||||||
|
std::mutex commandMutex_;
|
||||||
|
std::condition_variable commandCondition_;
|
||||||
|
|
||||||
|
enum CommandType {
|
||||||
|
CMD_LOAD_MODEL,
|
||||||
|
CMD_SET_ROTATION,
|
||||||
|
CMD_SET_TRANSLATION,
|
||||||
|
CMD_RESET_VIEW,
|
||||||
|
CMD_SET_CLEAR_COLOR,
|
||||||
|
CMD_RESIZE,
|
||||||
|
CMD_EXIT
|
||||||
|
};
|
||||||
|
|
||||||
|
struct RenderCommand {
|
||||||
|
CommandType type;
|
||||||
|
std::string param1; // For file path
|
||||||
|
float param2, param3, param4, param5;
|
||||||
|
RenderCommand() : type(CMD_EXIT), param1(""), param2(0.0f), param3(0.0f), param4(0.0f), param5(0.0f) {}
|
||||||
|
RenderCommand(CommandType t) : type(t), param1(""), param2(0), param3(0), param4(0), param5(0) {}
|
||||||
|
};
|
||||||
|
|
||||||
|
std::queue<RenderCommand> commandQueue_;
|
||||||
|
|
||||||
|
std::mutex callbackMutex_;
|
||||||
|
Callback renderCompleteCallback_;
|
||||||
|
|
||||||
|
int windowWidth_;
|
||||||
|
int windowHeight_;
|
||||||
|
};
|
||||||
|
} // namespace NaitveRenderThread
|
||||||
|
#endif //NATIVE_RENDER_THREAD_H
|
||||||
@ -29,6 +29,7 @@ static napi_value NativeLoadSoTest(napi_env env, napi_callback_info info)
|
|||||||
|
|
||||||
return sum;
|
return sum;
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace NativeOpenCAX {
|
namespace NativeOpenCAX {
|
||||||
EXTERN_C_START
|
EXTERN_C_START
|
||||||
static napi_value Init(napi_env env, napi_value exports) {
|
static napi_value Init(napi_env env, napi_value exports) {
|
||||||
@ -40,7 +41,7 @@ static napi_value Init(napi_env env, napi_value exports) {
|
|||||||
napi_property_descriptor desc[] = {
|
napi_property_descriptor desc[] = {
|
||||||
// [StartExclude napi_init_part]
|
// [StartExclude napi_init_part]
|
||||||
{"createNativeNode", nullptr, NativeManager::createNativeNode, nullptr, nullptr, nullptr,napi_default, nullptr },
|
{"createNativeNode", nullptr, NativeManager::createNativeNode, nullptr, nullptr, nullptr,napi_default, nullptr },
|
||||||
{"drawPattern", nullptr, NativeManager::NapiDrawPattern, nullptr, nullptr,nullptr, napi_default, nullptr},
|
{"loadModel", nullptr, NativeManager::NapiLoadModel, nullptr, nullptr, nullptr, napi_default, nullptr},
|
||||||
{"setFrameRate", nullptr, NativeManager::SetFrameRate, nullptr, nullptr, nullptr, napi_default, nullptr},
|
{"setFrameRate", nullptr, NativeManager::SetFrameRate, nullptr, nullptr, nullptr, napi_default, nullptr},
|
||||||
{"setNeedSoftKeyboard", nullptr, NativeManager::SetNeedSoftKeyboard, nullptr, nullptr, nullptr, napi_default,nullptr},
|
{"setNeedSoftKeyboard", nullptr, NativeManager::SetNeedSoftKeyboard, nullptr, nullptr, nullptr, napi_default,nullptr},
|
||||||
{"nativeLoadTest", nullptr, NativeLoadSoTest, nullptr, nullptr, nullptr, napi_default, nullptr},
|
{"nativeLoadTest", nullptr, NativeLoadSoTest, nullptr, nullptr, nullptr, napi_default, nullptr},
|
||||||
|
|||||||
30
entry/src/main/cpp/types/libopencax/Index.d.ts
vendored
30
entry/src/main/cpp/types/libopencax/Index.d.ts
vendored
@ -1,24 +1,6 @@
|
|||||||
/*
|
export interface NativeXOpenCAX {
|
||||||
* Copyright (c) 2024 Huawei Device Co., Ltd.
|
setFrameRate(nodeId: string, min: number, max: number, expected: number): void;
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
setNeedSoftKeyboard(nodeId: string, need: boolean): void;
|
||||||
* you may not use this file except in compliance with the License.
|
}
|
||||||
* You may obtain a copy of the License at
|
export function createNativeNode(nodeContent: any, nodeId: string): void;
|
||||||
*
|
export function loadModel(stepFilePath: string): void;
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
|
|
||||||
import { NodeContent } from '@ohos.arkui.node';
|
|
||||||
type XComponentContextStatus = {
|
|
||||||
hasDraw: boolean,
|
|
||||||
hasChangeColor: boolean
|
|
||||||
};
|
|
||||||
export const createNativeNode: (content: NodeContent, tag: string) => void;
|
|
||||||
export const drawPattern: () => void;
|
|
||||||
export const setFrameRate: (id: string, min: number, max: number, expected: number) => void;
|
|
||||||
export const setNeedSoftKeyboard: (id: string, needSoftKeyborad: boolean) => void;
|
|
||||||
@ -66,8 +66,7 @@ export struct ModelView {
|
|||||||
Button('加载模型').onClick(()=>{
|
Button('加载模型').onClick(()=>{
|
||||||
try {
|
try {
|
||||||
console.info('Model copied to:', this.modelPath);
|
console.info('Model copied to:', this.modelPath);
|
||||||
NativeOpenCAX.drawPattern();
|
NativeOpenCAX.loadModel(this.modelPath);
|
||||||
//NativeOpenCAX.loadModel(this.displayContrId,this.modelPath);
|
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
hilog.error(0x0000, 'ModelView', `LoadModel Failed: ${JSON.stringify(e)}`);
|
hilog.error(0x0000, 'ModelView', `LoadModel Failed: ${JSON.stringify(e)}`);
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user