├── .gitignore ├── .idea ├── compiler.xml ├── copyright │ └── profiles_settings.xml ├── gradle.xml ├── misc.xml ├── modules.xml ├── runConfigurations.xml └── vcs.xml ├── README.md ├── app ├── .gitignore ├── CMakeLists.txt ├── build.gradle ├── proguard-rules.pro └── src │ └── main │ ├── AndroidManifest.xml │ ├── cpp │ ├── GLRenderer.cpp │ ├── GLRenderer.h │ ├── GLrenderS.cpp │ ├── GLrenderS.h │ ├── gl_params.h │ ├── native-lib.cpp │ └── native-lib.h │ ├── java │ └── xingkong │ │ └── demo │ │ └── nativegl_demo │ │ ├── JNIProxy.java │ │ ├── MainActivity.java │ │ └── SViewHolder.java │ └── res │ ├── layout │ └── activity_main.xml │ ├── mipmap-hdpi │ ├── ic_launcher.png │ └── ic_launcher_round.png │ ├── mipmap-mdpi │ ├── ic_launcher.png │ └── ic_launcher_round.png │ ├── mipmap-xhdpi │ ├── ic_launcher.png │ └── ic_launcher_round.png │ ├── mipmap-xxhdpi │ ├── ic_launcher.png │ └── ic_launcher_round.png │ ├── mipmap-xxxhdpi │ ├── ic_launcher.png │ └── ic_launcher_round.png │ └── values │ ├── colors.xml │ ├── strings.xml │ └── styles.xml ├── build.gradle ├── gradle.properties ├── gradle └── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── gradlew ├── gradlew.bat └── settings.gradle /.gitignore: -------------------------------------------------------------------------------- 1 | *.iml 2 | .gradle 3 | /local.properties 4 | /.idea/workspace.xml 5 | /.idea/libraries 6 | .DS_Store 7 | /build 8 | /captures 9 | .externalNativeBuild 10 | -------------------------------------------------------------------------------- /.idea/compiler.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /.idea/copyright/profiles_settings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | -------------------------------------------------------------------------------- /.idea/gradle.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 17 | 18 | -------------------------------------------------------------------------------- /.idea/misc.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 19 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 46 | 47 | 48 | 49 | 50 | 1.8 51 | 52 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 68 | 69 | 70 | 71 | 72 | 73 | -------------------------------------------------------------------------------- /.idea/modules.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /.idea/runConfigurations.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 11 | 12 | -------------------------------------------------------------------------------- /.idea/vcs.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # NativeGL_demo 2 | 3 | ## 1方案介绍 4 | 在实际应用中,经常遇到OpenGL ES渲染性能达不到要求,图像卡顿等GG问题。这时,在不改变平台选型的情况下,选择一个好的方案实现OpenGL渲染很重要。 5 | 在android应用程序中使用OpenGL ES共有四种方案 6 | 1. 使用`GLSurfaceView`作为绘图的窗口,使用`GLSurfaceView.Renderer`实现OpenGL渲染上下文,并通过调用`android.opengl.GLES20`中的API函数实现对图像的渲染 7 | 2. 使用`GLSurfaceView`作为绘图的窗口,使用`GLSurfaceView.Renderer`实现OpenGL渲染上下文,和1不一样的是通过JNI接口调用`#include `中的API函数来实现图形渲染 8 | 3. 使用`NativeActivity`实现OpenGL渲染上下文,并通过JNI接口调用`#include `中的API函数来实现图形渲染。使用这种方案就意味着整个APP全部用C++语言编写,不能实现android基本控件的绘制,如Button/TextView 9 | 4. 最后一种方法,也是我所提倡使用的方法,就是使用SurfaceView作为绘图的窗口,并使用native层的pthread作为OpenGL渲染上下文,并通过pthread调用`#include `实现图形渲染 10 | 11 | 本例程以帮助类的形式将方案4的OpenGL渲染上下文封装在GLRender类中。用户使用时只需要继承GLRender类并像使用`GLSurfaceView.Renderer`接口一样,实现渲染上下文的回调函数,并在回调函数中调用`#include `中的API函数 12 | 13 | ## 2方案实现方法 14 | 15 | 使用本方案需要注意以下几点: 16 | 1. 编写CMakeLists.txt,添加如下语句。如果不添加会使程序编译GG。 17 | ``` cmake 18 | # now build app's shared lib 19 | #不加这句不能用std命名空间的函数 20 | set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11 -Wall") 21 | 22 | #使用这句将编译后的native-lib库和android、log、EGL、GLESv2四个库进行链接。 23 | #不加这个会GG,将导致上面提到的四个功能无法使用 24 | target_link_libraries( # Specifies the target library. 25 | native-lib 26 | # Links the target library to the log library 27 | # included in the NDK. 28 | android 29 | log 30 | EGL 31 | GLESv2 ) 32 | ``` 33 | 2. 在布局文件中定义一个SurfaceView,并实现SurfaceHolder.Callback接口。在接口中使用JNI调用GLRender.SetWindow函数将SurfaceView与NativeWindow关联。以以便在Native空间进行绘图。 34 | ``` c++ 35 | public class SViewHolder implements SurfaceHolder.Callback { 36 | //............... 37 | public void surfaceCreated(SurfaceHolder holder) { 38 | JNIProxy.SetSurfaceS(holder.getSurface()); 39 | JNIProxy.StartRenderS(); 40 | } 41 | //................ 42 | } 43 | ``` 44 | 3. 在Native空间继承GLRenderer类,并实现GLRenderer类中的以下抽象函数。不实现程序会GG 45 | ``` c++ 46 | /* 47 | * 下面三个函数为OpenGL渲染上下文回调函数,这三个函数需要用户通过继承GLRenderer类的方法来实现 48 | * 实现方法同android.opengl.GLSurfaceView.Render中的方法。详细请参考develop.google 49 | * */ 50 | virtual void SurfaceCreate()=0; 51 | virtual void SurfaceChange(int width, int height)=0; 52 | virtual void DrawFrame()=0; 53 | ``` 54 | -------------------------------------------------------------------------------- /app/.gitignore: -------------------------------------------------------------------------------- 1 | /build 2 | -------------------------------------------------------------------------------- /app/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # For more information about using CMake with Android Studio, read the 2 | # documentation: https://d.android.com/studio/projects/add-native-code.html 3 | 4 | # Sets the minimum version of CMake required to build the native library. 5 | 6 | cmake_minimum_required(VERSION 3.4.1) 7 | 8 | # now build app's shared lib 9 | set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11 -Wall") 10 | 11 | # Creates and names a library, sets it as either STATIC 12 | # or SHARED, and provides the relative paths to its source code. 13 | # You can define multiple libraries, and CMake builds them for you. 14 | # Gradle automatically packages shared libraries with your APK. 15 | 16 | add_library( # Sets the name of the library. 17 | native-lib 18 | 19 | # Sets the library as a shared library. 20 | SHARED 21 | 22 | # Provides a relative path to your source file(s). 23 | src/main/cpp/native-lib.cpp 24 | src/main/cpp/GLRenderer.cpp 25 | src/main/cpp/GLrenderS.cpp) 26 | 27 | # Searches for a specified prebuilt library and stores the path as a 28 | # variable. Because CMake includes system libraries in the search path by 29 | # default, you only need to specify the name of the public NDK library 30 | # you want to add. CMake verifies that the library exists before 31 | # completing its build. 32 | 33 | 34 | # Specifies libraries CMake should link to your target library. You 35 | # can link multiple libraries, such as libraries you define in this 36 | # build script, prebuilt third-party libraries, or system libraries. 37 | 38 | target_link_libraries( # Specifies the target library. 39 | native-lib 40 | 41 | # Links the target library to the log library 42 | # included in the NDK. 43 | android 44 | log 45 | EGL 46 | GLESv2 ) -------------------------------------------------------------------------------- /app/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'com.android.application' 2 | 3 | android { 4 | compileSdkVersion 26 5 | buildToolsVersion "25.0.2" 6 | defaultConfig { 7 | applicationId "xingkong.demo.nativegl_demo" 8 | minSdkVersion 15 9 | targetSdkVersion 26 10 | versionCode 1 11 | versionName "1.0" 12 | testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" 13 | externalNativeBuild { 14 | cmake { 15 | cppFlags "" 16 | } 17 | } 18 | } 19 | buildTypes { 20 | release { 21 | minifyEnabled false 22 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' 23 | } 24 | } 25 | externalNativeBuild { 26 | cmake { 27 | path "CMakeLists.txt" 28 | } 29 | } 30 | } 31 | 32 | dependencies { 33 | compile fileTree(dir: 'libs', include: ['*.jar']) 34 | androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2', { 35 | exclude group: 'com.android.support', module: 'support-annotations' 36 | }) 37 | compile 'com.android.support:appcompat-v7:26.+' 38 | compile 'com.android.support.constraint:constraint-layout:1.0.1' 39 | testCompile 'junit:junit:4.12' 40 | } 41 | -------------------------------------------------------------------------------- /app/proguard-rules.pro: -------------------------------------------------------------------------------- 1 | # Add project specific ProGuard rules here. 2 | # By default, the flags in this file are appended to flags specified 3 | # in D:\android-sdk/tools/proguard/proguard-android.txt 4 | # You can edit the include path and order by changing the proguardFiles 5 | # directive in build.gradle. 6 | # 7 | # For more details, see 8 | # http://developer.android.com/guide/developing/tools/proguard.html 9 | 10 | # Add any project specific keep options here: 11 | 12 | # If your project uses WebView with JS, uncomment the following 13 | # and specify the fully qualified class name to the JavaScript interface 14 | # class: 15 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview { 16 | # public *; 17 | #} 18 | 19 | # Uncomment this to preserve the line number information for 20 | # debugging stack traces. 21 | #-keepattributes SourceFile,LineNumberTable 22 | 23 | # If you keep the line number information, uncomment this to 24 | # hide the original source file name. 25 | #-renamesourcefileattribute SourceFile 26 | -------------------------------------------------------------------------------- /app/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /app/src/main/cpp/GLRenderer.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // Created by xingkong on 2017/9/21. 3 | // 4 | #include "GLRenderer.h" 5 | 6 | GLRenderer::GLRenderer() { 7 | pthread_mutex_init(&renderPara._mutex, 0); 8 | } 9 | 10 | GLRenderer::~GLRenderer() { 11 | pthread_join(renderPara._threadId,NULL); 12 | DestroyRender(); 13 | running=0; 14 | Inited=0; 15 | pthread_mutex_destroy(&renderPara._mutex); 16 | } 17 | 18 | //编译shader 19 | GLuint GLRenderer::loadShader(GLenum shaderType, const char* pSource) { 20 | GLuint shader = glCreateShader(shaderType); 21 | if (shader) { 22 | glShaderSource(shader, 1, &pSource, NULL); 23 | glCompileShader(shader); 24 | //检查错误 25 | GLint compiled = 0; 26 | glGetShaderiv(shader, GL_COMPILE_STATUS, &compiled); 27 | if (!compiled) { 28 | GLint infoLen = 0; 29 | glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &infoLen); 30 | if (infoLen) { 31 | char* buf = (char*) malloc(infoLen); 32 | if (buf) { 33 | glGetShaderInfoLog(shader, infoLen, NULL, buf); 34 | free(buf); 35 | } 36 | glDeleteShader(shader); 37 | shader = 0; 38 | } 39 | } 40 | } 41 | return shader; 42 | } 43 | 44 | //编译shader,创建project 45 | GLuint GLRenderer::createProgram(const char* pVertexSource, const char* pFragmentSource) { 46 | 47 | GLuint GvertexShader = loadShader(GL_VERTEX_SHADER, pVertexSource); //读取编译shader 48 | GLuint GpixelShader = loadShader(GL_FRAGMENT_SHADER, pFragmentSource); 49 | GLuint program = glCreateProgram(); 50 | if (program) { 51 | glAttachShader(program, GvertexShader); 52 | glAttachShader(program, GpixelShader); 53 | glLinkProgram(program); 54 | //检查错误 55 | GLint linkStatus = GL_FALSE; 56 | glGetProgramiv(program, GL_LINK_STATUS, &linkStatus); 57 | if (linkStatus != GL_TRUE) { 58 | GLint bufLength = 0; 59 | glGetProgramiv(program, GL_INFO_LOG_LENGTH, &bufLength); 60 | if (bufLength) { 61 | char* buf = (char*) malloc(bufLength); 62 | if (buf) { 63 | glGetProgramInfoLog(program, bufLength, NULL, buf); 64 | free(buf); 65 | } 66 | } 67 | glDeleteProgram(program); 68 | program = 0; 69 | } 70 | } 71 | return program; 72 | } 73 | 74 | void GLRenderer::SetWindow(JNIEnv *env, jobject surface) { 75 | // notify render thread that window has changed 76 | if (surface != 0) { 77 | renderPara._window = ANativeWindow_fromSurface(env, surface); 78 | pthread_mutex_lock(&renderPara._mutex); 79 | renderPara._msg = renderPara.MSG_WINDOW_SET; 80 | pthread_mutex_unlock(&renderPara._mutex); 81 | 82 | } else { 83 | ANativeWindow_release(renderPara._window); 84 | } 85 | return; 86 | } 87 | 88 | 89 | bool GLRenderer::InitRender(){ 90 | /* 91 | * Here specify the attributes of the desired configuration. 92 | * Below, we select an EGLConfig with at least 8 bits per color 93 | * component compatible with on-screen windows 94 | */ 95 | const EGLint attribs[] = { 96 | EGL_SURFACE_TYPE, EGL_WINDOW_BIT, 97 | EGL_BLUE_SIZE, 8, 98 | EGL_GREEN_SIZE, 8, 99 | EGL_RED_SIZE, 8, 100 | EGL_NONE 101 | }; 102 | EGLint attribList[] = { EGL_CONTEXT_CLIENT_VERSION, 2, EGL_NONE }; // OpenGL 2.0 103 | EGLint w, h, format; 104 | EGLint numConfigs; 105 | EGLConfig config; 106 | EGLSurface surface; 107 | EGLContext context; 108 | 109 | EGLDisplay display = eglGetDisplay(EGL_DEFAULT_DISPLAY); 110 | 111 | eglInitialize(display, 0, 0); 112 | /* Here, the application chooses the configuration it desires. 113 | * find the best match if possible, otherwise use the very first one 114 | */ 115 | eglChooseConfig(display, attribs, nullptr,0, &numConfigs); 116 | std::unique_ptr supportedConfigs(new EGLConfig[numConfigs]); 117 | // assert(supportedConfigs); 118 | eglChooseConfig(display, attribs, supportedConfigs.get(), numConfigs, &numConfigs); 119 | // assert(numConfigs); 120 | auto i = 0; 121 | for (; i < numConfigs; i++) { 122 | auto& cfg = supportedConfigs[i]; 123 | EGLint r, g, b, d; 124 | if (eglGetConfigAttrib(display, cfg, EGL_RED_SIZE, &r) && 125 | eglGetConfigAttrib(display, cfg, EGL_GREEN_SIZE, &g) && 126 | eglGetConfigAttrib(display, cfg, EGL_BLUE_SIZE, &b) && 127 | eglGetConfigAttrib(display, cfg, EGL_DEPTH_SIZE, &d) && 128 | r == 8 && g == 8 && b == 8 && d == 0 ) { 129 | 130 | config = supportedConfigs[i]; 131 | break; 132 | } 133 | } 134 | if (i == numConfigs) { 135 | config = supportedConfigs[0]; 136 | } 137 | 138 | /* EGL_NATIVE_VISUAL_ID is an attribute of the EGLConfig that is 139 | * guaranteed to be accepted by ANativeWindow_setBuffersGeometry(). 140 | * As soon as we picked a EGLConfig, we can safely reconfigure the 141 | * ANativeWindow buffers to match, using EGL_NATIVE_VISUAL_ID. */ 142 | eglGetConfigAttrib(display, config, EGL_NATIVE_VISUAL_ID, &format); 143 | surface = eglCreateWindowSurface(display, config,renderPara._window, NULL); 144 | context = eglCreateContext(display, config, NULL, attribList); 145 | 146 | if (eglMakeCurrent(display, surface, surface, context) == EGL_FALSE) { 147 | return -1; 148 | } 149 | 150 | eglQuerySurface(display, surface, EGL_WIDTH, &w); 151 | eglQuerySurface(display, surface, EGL_HEIGHT, &h); 152 | 153 | renderPara._display = display; 154 | renderPara._surface = surface; 155 | renderPara._context = context; 156 | renderPara._width=w; 157 | renderPara._height=h; 158 | glEnable(GL_CULL_FACE); 159 | // glShadeModel(GL_SMOOTH); 160 | glDisable(GL_DEPTH_TEST); 161 | 162 | SurfaceCreate(); 163 | SurfaceChange(w,h); 164 | 165 | window_seted=1; 166 | 167 | return true; 168 | } 169 | void GLRenderer::DestroyRender() { 170 | 171 | eglMakeCurrent(renderPara._display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT); 172 | eglDestroyContext(renderPara._display, renderPara._context); 173 | eglDestroySurface(renderPara._display, renderPara._surface); 174 | eglTerminate(renderPara._display); 175 | 176 | renderPara._display = EGL_NO_DISPLAY; 177 | renderPara._surface = EGL_NO_SURFACE; 178 | renderPara._context = EGL_NO_CONTEXT; 179 | 180 | return; 181 | } 182 | 183 | void GLRenderer::StartRenderThread(){ 184 | if(Inited==0){ 185 | pthread_create(&renderPara._threadId, 0, RenderThread, this); 186 | Inited=1; 187 | } 188 | running=1; 189 | } 190 | void GLRenderer::StopRenderThread() { 191 | 192 | // // send message to render thread to stop rendering 193 | // pthread_mutex_lock(&renderPara._mutex); 194 | // renderPara._msg = renderPara.MSG_RENDER_LOOP_EXIT; 195 | // pthread_mutex_unlock(&renderPara._mutex); 196 | // 197 | // pthread_join(renderPara._threadId, 0); 198 | // LOGE("Renderer thread stopped"); 199 | running=0; 200 | 201 | return; 202 | } 203 | 204 | void * GLRenderer::RenderThread(void *args){ 205 | GLRenderer *render= (GLRenderer*)args; 206 | render->RenderLoop(); 207 | pthread_exit(0); 208 | return 0; 209 | } 210 | 211 | void GLRenderer::RenderLoop(){ 212 | bool renderingEnabled = true; 213 | while (renderingEnabled) { 214 | if(running){ 215 | 216 | // process incoming messages 217 | if(renderPara._msg==renderPara.MSG_WINDOW_SET){ 218 | InitRender(); 219 | } 220 | if(renderPara._msg==renderPara.MSG_RENDER_LOOP_EXIT){ 221 | renderingEnabled = false; 222 | DestroyRender(); 223 | } 224 | renderPara._msg = renderPara.MSG_NONE; 225 | 226 | if(window_seted==0){ //如果没有初始化窗口,就不能启动 227 | usleep(16000); 228 | continue; 229 | } 230 | 231 | if (renderPara._display) { 232 | pthread_mutex_lock(&renderPara._mutex); 233 | DrawFrame(); 234 | if (!eglSwapBuffers(renderPara._display, renderPara._surface)) { 235 | // LOGE("GLrenderS::eglSwapBuffers() returned error %d", eglGetError()); 236 | } 237 | pthread_mutex_unlock(&renderPara._mutex); 238 | } 239 | else{ 240 | usleep(16000); //如果没有初始化好EGL,就等下一帧再渲染 241 | } 242 | } 243 | else{ 244 | usleep(16000); //如果没有初始化好EGL,就等下一帧再渲染 245 | } 246 | 247 | } 248 | 249 | } 250 | 251 | 252 | -------------------------------------------------------------------------------- /app/src/main/cpp/GLRenderer.h: -------------------------------------------------------------------------------- 1 | // 2 | // Created by xingkong on 2017/8/14. 3 | // 4 | 5 | #ifndef NATIVEGL_DEMO2_GLINTERFACE_H 6 | #define NATIVEGL_DEMO2_GLINTERFACE_H 7 | 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | #include 18 | #include 19 | #include 20 | 21 | 22 | class RenderPara{ 23 | 24 | public: 25 | 26 | enum RenderThreadMessage { 27 | MSG_NONE = 0, 28 | MSG_WINDOW_SET, 29 | MSG_RENDER_LOOP_EXIT 30 | }; 31 | pthread_t _threadId; 32 | pthread_mutex_t _mutex; 33 | enum RenderThreadMessage _msg; 34 | 35 | // android window, supported by NDK r5 and newer 36 | ANativeWindow* _window; 37 | 38 | EGLDisplay _display; 39 | EGLSurface _surface; 40 | EGLContext _context; 41 | 42 | EGLint _width; 43 | EGLint _height; 44 | }; 45 | 46 | class GLRenderer { 47 | private: 48 | RenderPara renderPara; 49 | 50 | // int start; 51 | bool Inited=0; 52 | bool running=0; 53 | bool window_seted=0; 54 | public: 55 | /* 56 | * 下面的函数为GLRender类内置函数,用户不需要实现 57 | * 其中声明为virtual的函数用户程序可覆盖实现 58 | * */ 59 | GLRenderer(); 60 | ~GLRenderer(); 61 | virtual GLuint loadShader(GLenum shaderType, const char* pSource); //加载着色器脚本(用户可调用 62 | virtual GLuint createProgram(const char* pVertexSource, const char* pFragmentSource); //创建OpenGL渲染工程(用户可调用 63 | virtual bool InitRender(); //初始化EGL 64 | virtual void DestroyRender(); //清除EGL 65 | static void * RenderThread(void *args); //OpenGL渲染线程入口 66 | virtual void RenderLoop(); //渲染线程主循环 67 | 68 | /* 69 | * 将OpenGL渲染的窗口关联到java空间的Surface对象。实现在SurfaceView上的绘图 70 | * @env:JNI方法传入的JNIEnv对象 71 | * @surface:Surface对象 72 | */ 73 | virtual void SetWindow(JNIEnv *env, jobject surface); 74 | /* 75 | * 开启OpenGL渲染线程。第一次调用时创建渲染线程。 76 | * 之后调用只是继续运行调用StartRenderThread函数后停止的渲染线程,并不会重新开启一个渲染线程。 77 | * 也就是说,每个GLRenderer对象只能创建一个渲染线程 78 | * */ 79 | virtual void StartRenderThread(); 80 | /* 81 | * 停止渲染线程,并不会释放线程资源,只是停止线程运行。 82 | * 当再次调用StartRenderThread函数后,线程继续运行。 83 | * */ 84 | virtual void StopRenderThread(); 85 | 86 | /* 87 | * 下面三个函数为OpenGL渲染上下文回调函数,这三个函数需要用户通过继承GLRenderer类的方法来实现 88 | * 实现方法同android.opengl.GLSurfaceView.Render中的方法。详细请参考develop.google 89 | * */ 90 | virtual void SurfaceCreate()=0; 91 | virtual void SurfaceChange(int width, int height)=0; 92 | virtual void DrawFrame()=0; 93 | }; 94 | 95 | 96 | 97 | #endif //PHASEDARRAY2_0_GLINTERFACE_H 98 | -------------------------------------------------------------------------------- /app/src/main/cpp/GLrenderS.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // Created by xingkong on 2017/8/14. 3 | // 4 | 5 | #include "GLrenderS.h" 6 | 7 | //S扫texture用的shader 8 | auto tVertexShader = 9 | "attribute vec2 a_Position;\n" //屏幕坐标 10 | "attribute vec2 a_TextureCoordinates;\n"//纹理坐标 11 | "varying vec2 v_TextureCoordinates;\n" 12 | "void main() {\n" 13 | " v_TextureCoordinates = a_TextureCoordinates;\n" 14 | " gl_Position = vec4(a_Position,0,1.0);\n" 15 | "}\n"; 16 | auto tFragmentShader = 17 | "precision mediump float;\n" 18 | "uniform sampler2D u_TextureUnit;\n" //S扫纹理采样器 19 | "varying vec2 v_TextureCoordinates;\n" //采样坐标 20 | "vec4 color_temp;\n" 21 | "void main() {\n" 22 | " color_temp = texture2D(u_TextureUnit, v_TextureCoordinates);\n" //使用v_TextureCoordinates采样u_TextureUnit中的颜色 23 | " if(color_temp.r<0.3125){\n" //使用伪彩色映射 24 | " color_temp=vec4(1.0-2.9875*color_temp.r,1.0-2.4*color_temp.r,1.0-0.1875*color_temp.r,1.0);\n" 25 | " }\n" 26 | " else if(color_temp.r<0.391){\n" 27 | " color_temp=vec4(0.0627+0.8*(color_temp.r-0.3125),0.25+6.4*(color_temp.r-0.3125),0.9375-11.2*(color_temp.r-0.3125),1.0);\n" 28 | " }\n" 29 | " else if(color_temp.r<0.46875){\n" 30 | " color_temp=vec4(0.125+8.0*(color_temp.r-0.391),0.75-1.6*(color_temp.r-0.391),0.0625-0.4*(color_temp.r-0.391),1.0);\n" 31 | " }\n" 32 | " else if(color_temp.r<0.625){\n" 33 | " color_temp=vec4(0.75+1.2*(color_temp.r-0.46875),0.625-1.6*(color_temp.r-0.46875),0.03127-0.2*(color_temp.r-0.46875),1.0);\n" 34 | " }\n" 35 | " else{\n" 36 | " color_temp=vec4(0.9375-1.2632*(color_temp.r-0.625),0.375-1.0*(color_temp.r-0.625),0.0,1.0);\n" 37 | " }\n" 38 | " gl_FragColor=color_temp;\n" 39 | "}\n"; 40 | 41 | 42 | GLrenderS::GLrenderS(){ 43 | 44 | } 45 | GLrenderS::~GLrenderS(){ 46 | 47 | } 48 | 49 | //读取texture 50 | void GLrenderS::loadTexture(){ 51 | glPixelStorei(GL_UNPACK_ALIGNMENT, 1); 52 | glGenTextures(1, &textureId); 53 | glActiveTexture(GL_TEXTURE0); 54 | glBindTexture(GL_TEXTURE_2D, textureId); 55 | glUniform1i(uTextureUnitLocation, 0); 56 | 57 | glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE, 1024, 64, 0, GL_LUMINANCE, GL_UNSIGNED_BYTE, sb_data); 58 | glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); //放大缩小使用的函数 59 | glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); 60 | } 61 | 62 | void GLrenderS::cal_pixel() { 63 | int i; 64 | float theta; 65 | for(i=0;ical_pixel(); 10 | } 11 | 12 | JNIEXPORT void JNICALL 13 | Java_xingkong_demo_nativegl_1demo_JNIProxy_StartRenderS(JNIEnv *env, jclass type) { 14 | renderS->StartRenderThread(); 15 | } 16 | 17 | JNIEXPORT void JNICALL 18 | Java_xingkong_demo_nativegl_1demo_JNIProxy_StopRenderS(JNIEnv *env, jclass type) { 19 | renderS->StopRenderThread(); 20 | } 21 | 22 | JNIEXPORT void JNICALL 23 | Java_xingkong_demo_nativegl_1demo_JNIProxy_SetSurfaceS(JNIEnv *env, jclass type, jobject surface) { 24 | renderS->SetWindow(env,surface); 25 | } 26 | } 27 | 28 | -------------------------------------------------------------------------------- /app/src/main/cpp/native-lib.h: -------------------------------------------------------------------------------- 1 | // 2 | // Created by xingkong on 2017/9/20. 3 | // 4 | 5 | #ifndef NATIVEGL_DEMO2_NATIVE_LIB_H 6 | #define NATIVEGL_DEMO2_NATIVE_LIB_H 7 | 8 | #include "GLrenderS.h" 9 | GLrenderS *renderS; 10 | unsigned char *sb_data; //S扫数据指针 11 | 12 | #endif //NATIVEGL_DEMO2_NATIVE_LIB_H 13 | -------------------------------------------------------------------------------- /app/src/main/java/xingkong/demo/nativegl_demo/JNIProxy.java: -------------------------------------------------------------------------------- 1 | /* 2 | *存放所有JNI接口函数 3 | * 4 | */ 5 | 6 | package xingkong.demo.nativegl_demo; 7 | 8 | import android.view.Surface; 9 | 10 | public class JNIProxy { 11 | static { 12 | System.loadLibrary("native-lib"); 13 | } 14 | //初始化函数 15 | public static native void CalPixel(); 16 | //OpenGL函数--使用Native方案调用OpenGL使用下面6个函数 17 | public static native void StartRenderS(); 18 | public static native void StopRenderS(); 19 | public static native void SetSurfaceS(Surface surface); 20 | } -------------------------------------------------------------------------------- /app/src/main/java/xingkong/demo/nativegl_demo/MainActivity.java: -------------------------------------------------------------------------------- 1 | package xingkong.demo.nativegl_demo; 2 | 3 | import android.os.Bundle; 4 | import android.support.v7.app.AppCompatActivity; 5 | import android.view.SurfaceView; 6 | 7 | public class MainActivity extends AppCompatActivity { 8 | private SurfaceView sSurfaceView=null; 9 | private SViewHolder sHolder=null; 10 | // Used to load the 'native-lib' library on application startup. 11 | 12 | 13 | @Override 14 | protected void onCreate(Bundle savedInstanceState) { 15 | super.onCreate(savedInstanceState); 16 | setContentView(R.layout.activity_main); 17 | 18 | JNIProxy.CalPixel(); 19 | sSurfaceView=(SurfaceView)findViewById(R.id.glViewS); 20 | sHolder=new SViewHolder(); 21 | sSurfaceView.getHolder().addCallback(sHolder); 22 | 23 | } 24 | @Override 25 | protected void onResume() { 26 | super.onResume(); 27 | // JNIProxy.StartRenderS(); 28 | } 29 | @Override 30 | protected void onStop() { 31 | super.onStop(); 32 | JNIProxy.StopRenderS(); 33 | } 34 | 35 | } 36 | -------------------------------------------------------------------------------- /app/src/main/java/xingkong/demo/nativegl_demo/SViewHolder.java: -------------------------------------------------------------------------------- 1 | package xingkong.demo.nativegl_demo; 2 | 3 | import android.view.SurfaceHolder; 4 | 5 | /** 6 | * Created by xingkong on 2017/8/17. 7 | */ 8 | 9 | public class SViewHolder implements SurfaceHolder.Callback { 10 | public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) { 11 | JNIProxy.SetSurfaceS(holder.getSurface()); 12 | JNIProxy.StartRenderS(); 13 | } 14 | 15 | public void surfaceCreated(SurfaceHolder holder) { 16 | JNIProxy.SetSurfaceS(holder.getSurface()); 17 | JNIProxy.StartRenderS(); 18 | } 19 | 20 | public void surfaceDestroyed(SurfaceHolder holder) { 21 | JNIProxy.SetSurfaceS(null); 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /app/src/main/res/layout/activity_main.xml: -------------------------------------------------------------------------------- 1 | 2 | 8 | 9 | 18 | 23 | 24 | 25 | -------------------------------------------------------------------------------- /app/src/main/res/mipmap-hdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhouxingkong/NativeGL_demo/0585dfd6b7131eea18d5aecdf9c0be8ae860167b/app/src/main/res/mipmap-hdpi/ic_launcher.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-hdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhouxingkong/NativeGL_demo/0585dfd6b7131eea18d5aecdf9c0be8ae860167b/app/src/main/res/mipmap-hdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-mdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhouxingkong/NativeGL_demo/0585dfd6b7131eea18d5aecdf9c0be8ae860167b/app/src/main/res/mipmap-mdpi/ic_launcher.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-mdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhouxingkong/NativeGL_demo/0585dfd6b7131eea18d5aecdf9c0be8ae860167b/app/src/main/res/mipmap-mdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhouxingkong/NativeGL_demo/0585dfd6b7131eea18d5aecdf9c0be8ae860167b/app/src/main/res/mipmap-xhdpi/ic_launcher.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xhdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhouxingkong/NativeGL_demo/0585dfd6b7131eea18d5aecdf9c0be8ae860167b/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhouxingkong/NativeGL_demo/0585dfd6b7131eea18d5aecdf9c0be8ae860167b/app/src/main/res/mipmap-xxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhouxingkong/NativeGL_demo/0585dfd6b7131eea18d5aecdf9c0be8ae860167b/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xxxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhouxingkong/NativeGL_demo/0585dfd6b7131eea18d5aecdf9c0be8ae860167b/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhouxingkong/NativeGL_demo/0585dfd6b7131eea18d5aecdf9c0be8ae860167b/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /app/src/main/res/values/colors.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | #3F51B5 4 | #303F9F 5 | #FF4081 6 | 7 | -------------------------------------------------------------------------------- /app/src/main/res/values/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | NativeGL_demo 3 | 4 | -------------------------------------------------------------------------------- /app/src/main/res/values/styles.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /build.gradle: -------------------------------------------------------------------------------- 1 | // Top-level build file where you can add configuration options common to all sub-projects/modules. 2 | 3 | buildscript { 4 | repositories { 5 | jcenter() 6 | } 7 | dependencies { 8 | classpath 'com.android.tools.build:gradle:2.3.3' 9 | 10 | // NOTE: Do not place your application dependencies here; they belong 11 | // in the individual module build.gradle files 12 | } 13 | } 14 | 15 | allprojects { 16 | repositories { 17 | jcenter() 18 | } 19 | } 20 | 21 | task clean(type: Delete) { 22 | delete rootProject.buildDir 23 | } 24 | -------------------------------------------------------------------------------- /gradle.properties: -------------------------------------------------------------------------------- 1 | # Project-wide Gradle settings. 2 | 3 | # IDE (e.g. Android Studio) users: 4 | # Gradle settings configured through the IDE *will override* 5 | # any settings specified in this file. 6 | 7 | # For more details on how to configure your build environment visit 8 | # http://www.gradle.org/docs/current/userguide/build_environment.html 9 | 10 | # Specifies the JVM arguments used for the daemon process. 11 | # The setting is particularly useful for tweaking memory settings. 12 | org.gradle.jvmargs=-Xmx1536m 13 | 14 | # When configured, Gradle will run in incubating parallel mode. 15 | # This option should only be used with decoupled projects. More details, visit 16 | # http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects 17 | # org.gradle.parallel=true 18 | -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhouxingkong/NativeGL_demo/0585dfd6b7131eea18d5aecdf9c0be8ae860167b/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | #Wed Sep 20 10:20:11 CST 2017 2 | distributionBase=GRADLE_USER_HOME 3 | distributionPath=wrapper/dists 4 | zipStoreBase=GRADLE_USER_HOME 5 | zipStorePath=wrapper/dists 6 | distributionUrl=https\://services.gradle.org/distributions/gradle-3.3-all.zip 7 | -------------------------------------------------------------------------------- /gradlew: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | ############################################################################## 4 | ## 5 | ## Gradle start up script for UN*X 6 | ## 7 | ############################################################################## 8 | 9 | # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 10 | DEFAULT_JVM_OPTS="" 11 | 12 | APP_NAME="Gradle" 13 | APP_BASE_NAME=`basename "$0"` 14 | 15 | # Use the maximum available, or set MAX_FD != -1 to use that value. 16 | MAX_FD="maximum" 17 | 18 | warn ( ) { 19 | echo "$*" 20 | } 21 | 22 | die ( ) { 23 | echo 24 | echo "$*" 25 | echo 26 | exit 1 27 | } 28 | 29 | # OS specific support (must be 'true' or 'false'). 30 | cygwin=false 31 | msys=false 32 | darwin=false 33 | case "`uname`" in 34 | CYGWIN* ) 35 | cygwin=true 36 | ;; 37 | Darwin* ) 38 | darwin=true 39 | ;; 40 | MINGW* ) 41 | msys=true 42 | ;; 43 | esac 44 | 45 | # Attempt to set APP_HOME 46 | # Resolve links: $0 may be a link 47 | PRG="$0" 48 | # Need this for relative symlinks. 49 | while [ -h "$PRG" ] ; do 50 | ls=`ls -ld "$PRG"` 51 | link=`expr "$ls" : '.*-> \(.*\)$'` 52 | if expr "$link" : '/.*' > /dev/null; then 53 | PRG="$link" 54 | else 55 | PRG=`dirname "$PRG"`"/$link" 56 | fi 57 | done 58 | SAVED="`pwd`" 59 | cd "`dirname \"$PRG\"`/" >/dev/null 60 | APP_HOME="`pwd -P`" 61 | cd "$SAVED" >/dev/null 62 | 63 | CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar 64 | 65 | # Determine the Java command to use to start the JVM. 66 | if [ -n "$JAVA_HOME" ] ; then 67 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then 68 | # IBM's JDK on AIX uses strange locations for the executables 69 | JAVACMD="$JAVA_HOME/jre/sh/java" 70 | else 71 | JAVACMD="$JAVA_HOME/bin/java" 72 | fi 73 | if [ ! -x "$JAVACMD" ] ; then 74 | die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME 75 | 76 | Please set the JAVA_HOME variable in your environment to match the 77 | location of your Java installation." 78 | fi 79 | else 80 | JAVACMD="java" 81 | which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 82 | 83 | Please set the JAVA_HOME variable in your environment to match the 84 | location of your Java installation." 85 | fi 86 | 87 | # Increase the maximum file descriptors if we can. 88 | if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then 89 | MAX_FD_LIMIT=`ulimit -H -n` 90 | if [ $? -eq 0 ] ; then 91 | if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then 92 | MAX_FD="$MAX_FD_LIMIT" 93 | fi 94 | ulimit -n $MAX_FD 95 | if [ $? -ne 0 ] ; then 96 | warn "Could not set maximum file descriptor limit: $MAX_FD" 97 | fi 98 | else 99 | warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT" 100 | fi 101 | fi 102 | 103 | # For Darwin, add options to specify how the application appears in the dock 104 | if $darwin; then 105 | GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" 106 | fi 107 | 108 | # For Cygwin, switch paths to Windows format before running java 109 | if $cygwin ; then 110 | APP_HOME=`cygpath --path --mixed "$APP_HOME"` 111 | CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` 112 | JAVACMD=`cygpath --unix "$JAVACMD"` 113 | 114 | # We build the pattern for arguments to be converted via cygpath 115 | ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` 116 | SEP="" 117 | for dir in $ROOTDIRSRAW ; do 118 | ROOTDIRS="$ROOTDIRS$SEP$dir" 119 | SEP="|" 120 | done 121 | OURCYGPATTERN="(^($ROOTDIRS))" 122 | # Add a user-defined pattern to the cygpath arguments 123 | if [ "$GRADLE_CYGPATTERN" != "" ] ; then 124 | OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)" 125 | fi 126 | # Now convert the arguments - kludge to limit ourselves to /bin/sh 127 | i=0 128 | for arg in "$@" ; do 129 | CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -` 130 | CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option 131 | 132 | if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition 133 | eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"` 134 | else 135 | eval `echo args$i`="\"$arg\"" 136 | fi 137 | i=$((i+1)) 138 | done 139 | case $i in 140 | (0) set -- ;; 141 | (1) set -- "$args0" ;; 142 | (2) set -- "$args0" "$args1" ;; 143 | (3) set -- "$args0" "$args1" "$args2" ;; 144 | (4) set -- "$args0" "$args1" "$args2" "$args3" ;; 145 | (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; 146 | (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; 147 | (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; 148 | (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; 149 | (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; 150 | esac 151 | fi 152 | 153 | # Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules 154 | function splitJvmOpts() { 155 | JVM_OPTS=("$@") 156 | } 157 | eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS 158 | JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME" 159 | 160 | exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@" 161 | -------------------------------------------------------------------------------- /gradlew.bat: -------------------------------------------------------------------------------- 1 | @if "%DEBUG%" == "" @echo off 2 | @rem ########################################################################## 3 | @rem 4 | @rem Gradle startup script for Windows 5 | @rem 6 | @rem ########################################################################## 7 | 8 | @rem Set local scope for the variables with windows NT shell 9 | if "%OS%"=="Windows_NT" setlocal 10 | 11 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 12 | set DEFAULT_JVM_OPTS= 13 | 14 | set DIRNAME=%~dp0 15 | if "%DIRNAME%" == "" set DIRNAME=. 16 | set APP_BASE_NAME=%~n0 17 | set APP_HOME=%DIRNAME% 18 | 19 | @rem Find java.exe 20 | if defined JAVA_HOME goto findJavaFromJavaHome 21 | 22 | set JAVA_EXE=java.exe 23 | %JAVA_EXE% -version >NUL 2>&1 24 | if "%ERRORLEVEL%" == "0" goto init 25 | 26 | echo. 27 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 28 | echo. 29 | echo Please set the JAVA_HOME variable in your environment to match the 30 | echo location of your Java installation. 31 | 32 | goto fail 33 | 34 | :findJavaFromJavaHome 35 | set JAVA_HOME=%JAVA_HOME:"=% 36 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe 37 | 38 | if exist "%JAVA_EXE%" goto init 39 | 40 | echo. 41 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 42 | echo. 43 | echo Please set the JAVA_HOME variable in your environment to match the 44 | echo location of your Java installation. 45 | 46 | goto fail 47 | 48 | :init 49 | @rem Get command-line arguments, handling Windowz variants 50 | 51 | if not "%OS%" == "Windows_NT" goto win9xME_args 52 | if "%@eval[2+2]" == "4" goto 4NT_args 53 | 54 | :win9xME_args 55 | @rem Slurp the command line arguments. 56 | set CMD_LINE_ARGS= 57 | set _SKIP=2 58 | 59 | :win9xME_args_slurp 60 | if "x%~1" == "x" goto execute 61 | 62 | set CMD_LINE_ARGS=%* 63 | goto execute 64 | 65 | :4NT_args 66 | @rem Get arguments from the 4NT Shell from JP Software 67 | set CMD_LINE_ARGS=%$ 68 | 69 | :execute 70 | @rem Setup the command line 71 | 72 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar 73 | 74 | @rem Execute Gradle 75 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS% 76 | 77 | :end 78 | @rem End local scope for the variables with windows NT shell 79 | if "%ERRORLEVEL%"=="0" goto mainEnd 80 | 81 | :fail 82 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of 83 | rem the _cmd.exe /c_ return code! 84 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 85 | exit /b 1 86 | 87 | :mainEnd 88 | if "%OS%"=="Windows_NT" endlocal 89 | 90 | :omega 91 | -------------------------------------------------------------------------------- /settings.gradle: -------------------------------------------------------------------------------- 1 | include ':app' 2 | --------------------------------------------------------------------------------