diff --git a/README.md b/README.md index 7b3e6fe4d0a44a53bf9a296931afe282ede4a42a..0087b3ee4221fad5a0f0c0ec6ff25431d00dce19 100644 --- a/README.md +++ b/README.md @@ -1,232 +1,190 @@ + + # EGLSurfaceView -EGLSurfaceView是一个类似GLSurfaceView的类,主要描画处理在C++层进行。它提供了完整的EGL管理和OpenGL ES渲染功能,支持多线程渲染和灵活的渲染模式。 +EGLSurfaceView 是一个专为 Android 平台设计的轻量级 OpenGL ES 渲染视图。它提供了一个简单的接口,用于在 Android 应用中进行 EGL 初始化、渲染和资源管理。 ## 特性 - -- 🎨 **完整的EGL管理**: 自动处理EGL初始化、配置选择、上下文创建和销毁 -- 🧵 **多线程渲染**: 独立的渲染线程,不阻塞UI线程 -- 🔄 **灵活的渲染模式**: 支持连续渲染和按需渲染两种模式 -- 🎯 **简单易用的API**: 类似GLSurfaceView的接口设计 -- 🛡️ **线程安全**: 内置线程同步机制 -- 📱 **Android原生支持**: 完全兼容Android NDK +- 支持 EGL 初始化与销毁 +- 支持设置渲染模式(连续渲染或按需渲染) +- 提供线程安全的渲染机制 +- 简单易用的接口设计,方便快速集成到 Android 项目中 +- 提供示例渲染器,便于学习与使用 ## 构成 -### Java层 -- **EGLSurfaceView.java**: 提供Surface管理和Java接口 - -### C++层 -- **EGLSurfaceView.h**: C++接口定义和类声明 -- **EGLSurfaceView.cpp**: EGL管理和渲染逻辑实现 -- **SampleRenderer.h/cpp**: 示例渲染器实现 +项目主要分为以下部分: -### 构建文件 -- **Android.mk**: NDK构建配置 -- **CMakeLists.txt**: CMake构建配置 +- **Java 层**:定义了 EGLSurfaceView 类和渲染器接口,负责与 Android SDK 交互。 +- **C++ 层**:实现了 EGL 的具体逻辑,包括显示初始化、上下文创建、表面管理、渲染线程等。 +- **构建文件**:支持使用 CMake 或 Android.mk 构建。 ## 快速开始 -### 1. 在Android项目中集成 +### 1. 在 Android 项目中集成 -将EGLSurfaceView文件复制到你的项目中,并在`build.gradle`中配置NDK: +确保你已将 `EGLSurfaceView` 作为模块引入到你的 Android 项目中。你可以通过以下方式集成: -```gradle -android { - compileSdk 33 - - defaultConfig { - ndk { - abiFilters 'arm64-v8a', 'armeabi-v7a' - } - } - - externalNativeBuild { - cmake { - path "src/main/cpp/CMakeLists.txt" - } - } -} -``` +- 将项目作为子模块添加到你的 Git 仓库 +- 直接复制 `library` 模块到你的项目中 ### 2. 在布局中使用 +在你的 XML 布局文件中添加 `EGLSurfaceView`: + ```xml - ``` -### 3. 在Activity中设置渲染器 +### 3. 在 Activity 中设置渲染器 + +在你的 `Activity` 中初始化 `EGLSurfaceView` 并设置渲染器: ```java public class MainActivity extends AppCompatActivity { - private EGLSurfaceView mEGLSurfaceView; - + private EGLSurfaceView eglSurfaceView; + private EGLSurfaceViewRendererDemo eglSurfaceViewDemo; + @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); - - mEGLSurfaceView = findViewById(R.id.egl_surface_view); - - // 设置渲染器(需要在C++层实现) - // mEGLSurfaceView.setRenderer(new MyRenderer()); - - // 设置渲染模式 - mEGLSurfaceView.setRenderMode(EGLSurfaceView.RENDERMODE_CONTINUOUSLY); + + eglSurfaceView = findViewById(R.id.egl_surface_view); + eglSurfaceViewDemo = new EGLSurfaceViewRendererDemo(); + + eglSurfaceView.setRenderer(eglSurfaceViewDemo.getNativePtr()); + eglSurfaceView.setRenderMode(EGLSurfaceView.RENDERMODE_CONTINUOUSLY); } - + + @Override + protected void onDestroy() { + super.onDestroy(); + eglSurfaceViewDemo.onDestroy(); + eglSurfaceView.onPause(); + } + @Override protected void onResume() { super.onResume(); - mEGLSurfaceView.onResume(); + eglSurfaceView.onResume(); } - + @Override protected void onPause() { super.onPause(); - mEGLSurfaceView.onPause(); + eglSurfaceView.onPause(); } } ``` -## API文档 +## API 文档 ### Java API -#### EGLSurfaceView类 - -```java -public class EGLSurfaceView extends SurfaceView implements SurfaceHolder.Callback -``` - -**主要方法:** +#### `EGLSurfaceView` 类 -- `setRenderer(Renderer renderer)`: 设置渲染器 -- `setRenderMode(int renderMode)`: 设置渲染模式 -- `getRenderMode()`: 获取当前渲染模式 -- `requestRender()`: 请求渲染(仅在RENDERMODE_WHEN_DIRTY模式下有效) -- `onResume()`: 恢复渲染 -- `onPause()`: 暂停渲染 +`EGLSurfaceView` 是一个继承自 `SurfaceView` 的自定义视图,用于进行 EGL 渲染。 -**渲染模式:** +##### 方法 +- `setRenderer(long renderer)`:设置本地渲染器对象 +- `setRenderMode(int mode)`:设置渲染模式(`RENDERMODE_CONTINUOUSLY` 或 `RENDERMODE_WHEN_DIRTY`) +- `getRenderMode()`:获取当前的渲染模式 +- `requestRender()`:请求渲染 +- `onResume()`:恢复渲染 +- `onPause()`:暂停渲染 -- `RENDERMODE_CONTINUOUSLY`: 连续渲染模式(默认) -- `RENDERMODE_WHEN_DIRTY`: 按需渲染模式 +#### `Renderer` 接口 -#### Renderer接口 - -```java -public interface Renderer { - void onSurfaceCreated(); - void onSurfaceChanged(int width, int height); - void onDrawFrame(); - void onSurfaceDestroyed(); -} -``` +`Renderer` 是一个接口,用于实现渲染逻辑。示例渲染器为 `EGLSurfaceViewRendererDemo`。 ### C++ API -#### EGLSurfaceView类 - -```cpp -class EGLSurfaceView { -public: - enum RenderMode { - RENDERMODE_WHEN_DIRTY = 0, - RENDERMODE_CONTINUOUSLY = 1 - }; - - class Renderer { - public: - virtual void onSurfaceCreated() = 0; - virtual void onSurfaceChanged(int width, int height) = 0; - virtual void onDrawFrame() = 0; - virtual void onSurfaceDestroyed() = 0; - }; - - void setRenderer(std::shared_ptr renderer); - void setRenderMode(RenderMode mode); - void requestRender(); - // ... 其他方法 -}; -``` +#### `EGLSurfaceView` 类 + +`EGLSurfaceView` 是一个 C++ 类,负责 EGL 的初始化、销毁、渲染管理。 + +##### 方法 +- `setRenderer(std::shared_ptr)`:设置渲染器 +- `setRenderMode(RenderMode)`:设置渲染模式(连续渲染或按需渲染) +- `requestRender()`:请求渲染 +- `surfaceCreated(ANativeWindow*)`:创建 EGL 表面 +- `surfaceChanged(int width, int height)`:调整视图尺寸 +- `surfaceDestroyed()`:销毁 EGL 表面 +- `pause()`:暂停渲染线程 +- `resume()`:恢复渲染线程 +- `initEGL()`:初始化 EGL +- `createEGLSurface()`:创建 EGL 渲染表面 +- `destroyEGLSurface()`:销毁 EGL 渲染表面 +- `renderThreadFunc()`:渲染线程的主函数 +- `doRender()`:执行一帧的渲染 ## 示例渲染器 -项目包含了一个完整的示例渲染器`SampleRenderer`,展示了如何: - -- 创建和编译着色器 -- 设置顶点数据和属性 -- 实现基本的3D变换 -- 处理OpenGL ES错误 +示例渲染器 `EGLSurfaceViewRendererDemo` 是一个简单的 OpenGL ES 渲染器,用于演示如何使用 EGLSurfaceView。 ### 使用示例渲染器 -```cpp -// 在C++层创建和设置渲染器 -auto renderer = std::make_shared(); -eglSurfaceView->setRenderer(renderer); -``` +`EGLSurfaceViewRendererDemo` 提供了基本的 OpenGL 初始化、着色器编译与渲染逻辑。你可以通过继承此类或使用其方法来构建你自己的渲染器。 ## 构建说明 -### 使用CMake构建 +### 使用 CMake 构建 + +确保你已配置 `CMakeLists.txt` 文件,并正确设置所有依赖项。使用以下命令进行构建: ```bash -mkdir build -cd build -cmake .. +cmake . make ``` -### 使用Android.mk构建 +### 使用 Android.mk 构建 + +你也可以使用 `Android.mk` 构建项目: ```bash -ndk-build +ndk-build -C jni ``` ## 依赖库 -- **Android NDK**: 用于C++开发 -- **EGL**: OpenGL ES渲染上下文管理 -- **OpenGL ES 3.0+**: 图形渲染API -- **Android Native Window**: Surface管理 +- Android NDK +- OpenGL ES 2.0 或以上 +- C++ STL 支持 ## 注意事项 -1. **线程安全**: 所有OpenGL调用必须在渲染线程中进行 -2. **资源管理**: 确保在`onSurfaceDestroyed`中正确释放OpenGL资源 -3. **生命周期**: 正确处理Activity的生命周期回调 -4. **错误处理**: 建议在开发阶段启用OpenGL错误检查 +- 确保在主线程中创建 EGLSurfaceView +- 在 Activity 的生命周期中正确调用 `onResume()` 和 `onPause()` +- 使用 `requestRender()` 时确保渲染模式为 `RENDERMODE_WHEN_DIRTY` ## 性能优化建议 -1. **减少状态切换**: 批量处理相同状态的渲染操作 -2. **使用VBO**: 避免每帧重复上传顶点数据 -3. **纹理管理**: 合理使用纹理图集和压缩格式 -4. **着色器优化**: 避免在片段着色器中进行复杂计算 +- 尽量减少频繁的 `requestRender()` 调用 +- 合理管理 OpenGL 资源的创建与销毁 +- 避免在渲染线程中执行耗时操作 ## 故障排除 ### 常见问题 -1. **黑屏问题**: 检查EGL初始化和着色器编译状态 -2. **崩溃问题**: 确保在正确的线程中调用OpenGL函数 -3. **性能问题**: 使用GPU调试工具分析渲染瓶颈 +1. **EGL 初始化失败**:请检查设备是否支持 OpenGL ES 2.0 或以上版本 +2. **渲染线程卡死**:确保没有阻塞渲染线程的操作 +3. **Surface 创建失败**:请检查 `ANativeWindow` 是否有效 ### 调试技巧 -- 启用OpenGL错误检查 -- 使用Android GPU Inspector -- 添加详细的日志输出 +- 使用 `checkEGLError()` 检查 EGL 错误 +- 使用 `checkShaderCompileStatus()` 和 `checkProgramLinkStatus()` 检查着色器编译与链接状态 +- 使用日志记录关键函数的调用流程 ## 许可证 -MIT License +本项目基于 [Apache-2.0 License](LICENSE) 开源。 ## 贡献 -欢迎提交Issue和Pull Request来改进这个项目。 \ No newline at end of file +欢迎贡献代码!请提交 PR 或 Issue 到项目仓库。 \ No newline at end of file