diff --git a/README.en.md b/README.en.md new file mode 100644 index 0000000000000000000000000000000000000000..73a72a9ae9ff4715fefc7af9456066b05f9ccf5b --- /dev/null +++ b/README.en.md @@ -0,0 +1,91 @@ +# OpenGL Tetrahedron + +### Overview + +The XComponent is frequently used for displaying camera preview streams and rendering game graphics. In HarmonyOS, it can be combined with the NativeWindow to create an OpenGL development environment, allowing you to display graphics rendered using OpenGL on the XComponent. This sample, based on the Native C++ template, uses OpenGL (OpenGL ES) API calls to draw a 3D shape (tetrahedron) and render it on the XComponent of the page. The sample also includes an auto rotation button for continuous spinning and a damped rotation button that slows down the rotation until it stops. In addition, you can manipulate the tetrahedron by swiping on the screen, presenting the shape from various perspectives on the page. + +### Preview + +| Home page | Rotated drawing | +|:-------------------------------------------------------------------------------------:|:-------------------------------------:| +| ![](screenshots/device/index.en.png) | ![](screenshots/device/rotate.en.png) | + + +### How to Use + +The app's UI demonstrates the use of the XComponent and employs OpenGL (OpenGL ES) standard APIs to render a 3D graphic (tetrahedron), with a simple linear light source for the 3D illumination. You can swipe across the screen to rotate the tetrahedron. The primary method for updating the 3D graphic's rotation angle is through the NAPI interface. + +### Project Directory + +``` +├──entry/src/main/cpp/ +│ ├──CMakeLists.txt // CMake build script +│ ├──app_napi.cpp // Native APIs +│ ├──include +│ │ ├──app_napi.h +│ │ ├──tetrahedron.h +│ │ ├──frame_handle.h +│ │ └──util +│ │ ├──log.h +│ │ ├──napi_manager.h +│ │ ├──napi_util.h +│ │ └──native_common.h +│ ├──module.cpp // NAPI module registration +│ ├──napi_manager.cpp +│ ├──napi_util.cpp +│ ├──frame_handle.cpp +│ ├──tetrahedron.cpp // OpenGL (ES) tetrahedron implementation +│ └──type +│ └──libentry +│ ├──oh-package.json5 +│ └──tetrahedron_napi.d.ts // Exported APIs +├──entry/src/main/ets +│ ├──entryability +│ │ └──EntryAbility.ets +│ ├──pages +│ │ └──Index.ets // Home page +│ └──utils +│ │ └──Logger.ets // Log utility +└──entry/src/main/resources // Static resources +``` + +### How to Implement + +Create a native C++ project in DevEco Studio, define the **Init** and **Update** functions in the C++ code for initializing the 3D graphics rendering environment and updating the graphics rendering, respectively. Map the NAPI interface **UpdateAngle**. On the ArkTS side, use the XComponent to implement **Index.ets**. On the C++ side, use the OpenGL ES standard APIs to handle the rendering process of the tetrahedron and to facilitate the interaction with ArkTS. + +Upon app launch, the NAPI module is initialized, and **OH_NativeXComponent_GetXComponentId()** is used on the C++ side to obtain the pointer to the XComponent. This pointer is then passed to the **Init** and **Update** functions for rendering the 3D graphics. To enable the rotation of the tetrahedron via touchscreen gestures, the NAPI interface **UpdateAngle** mapping in the C++ code is called on the ArkTS side. For this to work, ArkTS must correctly import the **libtetrahedron_napi.so** file of the NAPI module and call the **UpdateAngle** API declared in **src/main/cpp/type/libentry/tetrahedron_napi.d.ts** to adjust the rotation angle of the tetrahedron. + +For details about the source code, see [napi_manager.cpp](entry/src/main/cpp/napi_manager.cpp), [app_napi.cpp](entry/src/main/cpp/app_napi.cpp), and [tetrahedron.cpp](entry/src/main/cpp/tetrahedron.cpp). + +Native XComponent functions are as follows: + +| Name | Description | +| ------------------------------------------------------------------------------------------------------------------------------------------------ | -------------------------------- | +| OH_NativeXComponent_GetXComponentId(OH_NativeXComponent *component, char *id, uint64_t *size) | Obtain the ID of the ArkUI XComponent. | +| OH_NativeXComponent_GetXComponentSize(OH_NativeXComponent *component, const void *window, uint64_t *width, uint64_t *height) | Obtains the size of the surface held by the ArkUI XComponent. | +| OH_NativeXComponent_GetXComponentOffset(OH_NativeXComponent *component, const void *window, double *x, double *y) | Obtains the offset of the ArkUI XComponent relative to the upper left vertex of the screen.| +| OH_NativeXComponent_GetTouchEvent(OH_NativeXComponent *component, const void *window, OH_NativeXComponent_TouchEvent *touchEvent) | Obtains the touch event scheduled by the ArkUI XComponent. | +| OH_NativeXComponent_GetTouchPointToolType(OH_NativeXComponent *component, uint32_t pointIndex, OH_NativeXComponent_TouchPointToolType *toolType) | Obtains the ArkUI XComponent touch point tool type. | +| OH_NativeXComponent_GetTouchPointTiltX(OH_NativeXComponent *component, uint32_t pointIndex, float *tiltX) | Obtains the angle between the Y-Z plane of the ArkUI XComponent touch point and the x-axis. | +| OH_NativeXComponent_GetTouchPointTiltY(OH_NativeXComponent *component, uint32_t pointIndex, float *tiltY) | Obtains the angle between the X-Z plane of the ArkUI XComponent touch point and the y-axis. | +| OH_NativeXComponent_GetMouseEvent(OH_NativeXComponent *component, const void *window, OH_NativeXComponent_MouseEvent *mouseEvent) | Obtains the mouse event scheduled by ArkUI XComponent. | +| OH_NativeXComponent_RegisterCallback(OH_NativeXComponent *component, OH_NativeXComponent_Callback *callback) | Registers a callback for this instance. | +| OH_NativeXComponent_RegisterMouseEventCallback(OH_NativeXComponent *component, OH_NativeXComponent_MouseEvent_Callback *callback) | Registers a mouse event callback for this instance. | + +### Required Permissions + +N/A + +### Dependencies + +N/A + +### Constraints + +1. The sample app is supported only on Huawei phones running the standard system. + +2. The HarmonyOS version must be HarmonyOS NEXT Developer Beta1 or later. + +3. The DevEco Studio version must be DevEco Studio NEXT Developer Beta1 or later. + +4. The HarmonyOS SDK version must be HarmonyOS NEXT Developer Beta1 or later. diff --git a/entry/src/main/ets/pages/Index.ets b/entry/src/main/ets/pages/Index.ets index 6e92c822bf71f0b07112a7b61c745d3ca2c46886..1f31fabef5c3ed96e9e0076d0d47f0f61fffbef7 100644 --- a/entry/src/main/ets/pages/Index.ets +++ b/entry/src/main/ets/pages/Index.ets @@ -15,14 +15,12 @@ import { Logger } from '../utils/Logger'; import tetrahedron_napi from 'libtetrahedron_napi.so'; -import { resourceManager } from '@kit.LocalizationKit'; import { RotationType } from '../utils/Constants'; @Entry @Component struct Index { @State angleArray: Array = new Array(); - @State shaftRotation: string = ''; @State enableRotate: boolean = false; private xComponentId = 'tetrahedron'; private panOption: PanGestureOptions = new PanGestureOptions({ direction: PanDirection.All }); @@ -31,8 +29,6 @@ struct Index { Logger.info('aboutToAppear'); this.angleArray[0] = 30; this.angleArray[1] = 45; - let resourceManager: resourceManager.ResourceManager = getContext(this).resourceManager; - this.shaftRotation = await resourceManager.getStringValue($r('app.string.shaftRotation').id); } build() { @@ -47,8 +43,12 @@ struct Index { .textAlign(TextAlign.Start) .margin({ top: $r('app.float.wh_value_13'), bottom: $r('app.float.wh_value_15') }) - Text('X ' + this.shaftRotation + ':' + this.angleArray[0].toString() - + '°\nY ' + this.shaftRotation + ':' + this.angleArray[1].toString() + '°') + Text() { + Span($r('app.string.x_shaft_rotation')) + Span(this.angleArray[0].toString() + '°\n') + Span($r('app.string.y_shaft_rotation')) + Span(this.angleArray[1].toString() + '°') + } .fontSize($r('app.float.head_font_24')) .lineHeight($r('app.float.wh_value_33')) .fontFamily('HarmonyHeiTi-Bold') diff --git a/entry/src/main/resources/base/element/string.json b/entry/src/main/resources/base/element/string.json index 3b41e683933d16e86321df0bb8cee01b64ddbd73..823d4b35d7e8371734bc759f988b6c6545a6a682 100644 --- a/entry/src/main/resources/base/element/string.json +++ b/entry/src/main/resources/base/element/string.json @@ -6,19 +6,23 @@ }, { "name": "EntryAbility_desc", - "value": "description" + "value": "OpenGL Tetrahedron" }, { - "name": "EntryAbility_label", - "value": "Tetrahedron" + "name": "x_shaft_rotation", + "value": "Rotation angle around x axis:" + }, + { + "name": "y_shaft_rotation", + "value": "Rotation angle around y axis:" }, { - "name": "shaftRotation", - "value": "Shaft Rotation" + "name": "EntryAbility_label", + "value": "Tetrahedron" }, { "name": "btn_auto_rotation", - "value": "Start" + "value": "Auto" }, { "name": "btn_stop_rotation", @@ -26,7 +30,7 @@ }, { "name": "btn_damping_rotation", - "value": "Damping" + "value": "Damped" } ] } \ No newline at end of file diff --git a/entry/src/main/resources/en_US/element/string.json b/entry/src/main/resources/en_US/element/string.json index 48b10e599be74d66059041d6de5c90de793a6e68..823d4b35d7e8371734bc759f988b6c6545a6a682 100644 --- a/entry/src/main/resources/en_US/element/string.json +++ b/entry/src/main/resources/en_US/element/string.json @@ -9,8 +9,12 @@ "value": "OpenGL Tetrahedron" }, { - "name": "shaftRotation", - "value": "Shaft Rotation" + "name": "x_shaft_rotation", + "value": "Rotation angle around x axis:" + }, + { + "name": "y_shaft_rotation", + "value": "Rotation angle around y axis:" }, { "name": "EntryAbility_label", @@ -18,7 +22,7 @@ }, { "name": "btn_auto_rotation", - "value": "Start" + "value": "Auto" }, { "name": "btn_stop_rotation", @@ -26,7 +30,7 @@ }, { "name": "btn_damping_rotation", - "value": "Damping" + "value": "Damped" } ] } \ No newline at end of file diff --git a/entry/src/main/resources/zh_CN/element/string.json b/entry/src/main/resources/zh_CN/element/string.json index ea8d5b34f787011b1ba3ef03bbef23b6a60f9b55..80b17b3b2e22ce05a3f78911136e5a3a819371f7 100644 --- a/entry/src/main/resources/zh_CN/element/string.json +++ b/entry/src/main/resources/zh_CN/element/string.json @@ -9,8 +9,12 @@ "value": "OpenGL 三棱锥" }, { - "name": "shaftRotation", - "value": "轴旋转" + "name": "x_shaft_rotation", + "value": "X轴旋转:" + }, + { + "name": "y_shaft_rotation", + "value": "Y轴旋转:" }, { "name": "EntryAbility_label", diff --git a/screenshots/device/index.en.png b/screenshots/device/index.en.png new file mode 100644 index 0000000000000000000000000000000000000000..931ad665ed0ff61465d4cc78c480fa44ba536240 Binary files /dev/null and b/screenshots/device/index.en.png differ diff --git a/screenshots/device/rotate.en.png b/screenshots/device/rotate.en.png new file mode 100644 index 0000000000000000000000000000000000000000..3c1683709c7e52ff08a886fab8bf31a6bc90b4d8 Binary files /dev/null and b/screenshots/device/rotate.en.png differ