From b528a96e3b31dd6ea48c9b37d713136248035cfa Mon Sep 17 00:00:00 2001 From: Vadim Lopatin Date: Thu, 21 Apr 2016 09:41:47 +0300 Subject: [PATCH] Android support; now can show window -- #119 --- 3rdparty/android/log.d | 2 +- examples/android/build_apk.sh | 2 +- examples/android/jni/main.d | 20 ++++++--- src/dlangui/graphics/glsupport.d | 58 ++++++++++++++++---------- src/dlangui/platforms/common/startup.d | 1 + 5 files changed, 52 insertions(+), 31 deletions(-) diff --git a/3rdparty/android/log.d b/3rdparty/android/log.d index 26dc5e92..dfd4ed7c 100644 --- a/3rdparty/android/log.d +++ b/3rdparty/android/log.d @@ -28,7 +28,7 @@ int __android_log_print(int prio, const(char)* tag, const(char)* fmt, ...); int __android_log_vprint(int prio, const(char)* tag, const(char)* fmt, va_list ap); void __android_log_assert(const(char)* cond, const(char)* tag, const(char)* fmt, ...); -__gshared const(char) * ANDROID_LOG_TAG = "dlangui_app"; +__gshared const(char) * ANDROID_LOG_TAG = "dlangui"; void LOGI(S...)(const(char) * fmt, S args) { __android_log_print(android_LogPriority.ANDROID_LOG_INFO, ANDROID_LOG_TAG, fmt, args); diff --git a/examples/android/build_apk.sh b/examples/android/build_apk.sh index 243be474..848a720a 100755 --- a/examples/android/build_apk.sh +++ b/examples/android/build_apk.sh @@ -74,7 +74,7 @@ mkdir -p build/$PLATFORM_DIR/ echo "\nCompiling $OBJFILE...\n" #========================================================= -$LDC/bin/ldc2 $LDC_PARAMS $SOURCE_PATHS $SOURCES -c -singleobj -of=$OBJFILE || die 2 "ldc2 build for $OBJFILE is failed" +$LDC/bin/ldc2 $LDC_PARAMS $SOURCE_PATHS $SOURCES -d-debug -d-version=EmbedStandardResources -c -singleobj -of=$OBJFILE || die 2 "ldc2 build for $OBJFILE is failed" echo "\n\nLinking $TARGET...\n" #========================================================= diff --git a/examples/android/jni/main.d b/examples/android/jni/main.d index f1656ea2..26616982 100644 --- a/examples/android/jni/main.d +++ b/examples/android/jni/main.d @@ -15,7 +15,7 @@ * */ -version(Android): +//version(Android): import core.stdc.stdlib : malloc; import core.stdc.string : memset; @@ -142,12 +142,13 @@ class AndroidPlatform : Platform { */ int engine_init_display() { // initialize OpenGL ES and EGL + Log.i("engine_init_display"); /* - * Here specify the attributes of the desired configuration. - * Below, we select an EGLConfig with at least 8 bits per color - * component compatible with on-screen windows - */ + * Here specify the attributes of the desired configuration. + * Below, we select an EGLConfig with at least 8 bits per color + * component compatible with on-screen windows + */ const(EGLint)[9] attribs = [ EGL_SURFACE_TYPE, EGL_WINDOW_BIT, EGL_BLUE_SIZE, 8, @@ -179,7 +180,8 @@ class AndroidPlatform : Platform { ANativeWindow_setBuffersGeometry(_appstate.window, 0, 0, format); surface = eglCreateWindowSurface(display, config, _appstate.window, null); - context = eglCreateContext(display, config, null, null); + EGLint[3] contextAttrs = [EGL_CONTEXT_CLIENT_VERSION, 3, EGL_NONE]; + context = eglCreateContext(display, config, null, contextAttrs.ptr); if (eglMakeCurrent(display, surface, surface, context) == EGL_FALSE) { LOGW("Unable to eglMakeCurrent"); @@ -214,6 +216,7 @@ class AndroidPlatform : Platform { * Tear down the EGL context currently associated with the display. */ void engine_term_display() { + Log.i("engine_term_display"); if (_display != EGL_NO_DISPLAY) { eglMakeCurrent(_display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT); if (_context != EGL_NO_CONTEXT) { @@ -234,6 +237,7 @@ class AndroidPlatform : Platform { * Process the next input event. */ int handle_input(AInputEvent* event) { + Log.i("handle input, event=", AInputEvent_getType(event)); if (AInputEvent_getType(event) == AINPUT_EVENT_TYPE_MOTION) { _engine.animating = 1; _engine.state.x = AMotionEvent_getX(event, 0); @@ -247,6 +251,7 @@ class AndroidPlatform : Platform { * Process the next main command. */ void handle_cmd(int cmd) { + Log.i("handle cmd=", cmd); switch (cmd) { case APP_CMD_SAVE_STATE: // The system has asked us to save our current state. Do so. @@ -332,6 +337,7 @@ class AndroidPlatform : Platform { GLDrawBuf _drawbuf; void drawWindow(AndroidWindow w = null) { + Log.i("drawWindow"); if (w is null) w = activeWindow; else if (!(activeWindow is w)) @@ -528,7 +534,9 @@ extern (C) void android_main(android_app* state) { version (unittest) { } else { + Log.i("Calling UIAppMain"); res = UIAppMain([]); + Log.i("UIAppMain returned with resultCode=", res); } // loop waiting for stuff to do. diff --git a/src/dlangui/graphics/glsupport.d b/src/dlangui/graphics/glsupport.d index 8a5d61a7..7d8cf45e 100644 --- a/src/dlangui/graphics/glsupport.d +++ b/src/dlangui/graphics/glsupport.d @@ -74,6 +74,9 @@ import dlangui.graphics.scene.mesh; import dlangui.graphics.scene.effect; +//extern (C) void func(int n); +//pragma(msg, __traits(identifier, func)); + /** * Convenient wrapper around glGetError() * Using: checkgl!glFunction(funcParams); @@ -83,7 +86,11 @@ template checkgl(alias func) { debug auto checkgl(string functionName=__FUNCTION__, int line=__LINE__, Args...)(Args args) { - scope(success) checkError(func.stringof, functionName, line); + version (Android) { + scope(success) checkError(__traits(identifier, func), functionName, line); + } else { + scope(success) checkError(func.stringof, functionName, line); + } return func(args); } else alias checkgl = func; @@ -169,40 +176,42 @@ class GLProgram : dlangui.graphics.scene.mesh.GraphicsEffect { import std.string : toStringz, fromStringz; char[] sourceCode; - sourceCode ~= "#version "; - sourceCode ~= glslversionString; - sourceCode ~= "\n"; + if (glslversionString.length) { + sourceCode ~= "#version "; + sourceCode ~= glslversionString; + sourceCode ~= "\n"; + } sourceCode ~= src; compatibilityFixes(sourceCode, type); - Log.d("compileShader: glsl = ", glslversion, ", type: ", (type == GL_VERTEX_SHADER ? "GL_VERTEX_SHADER" : (type == GL_FRAGMENT_SHADER ? "GL_FRAGMENT_SHADER" : "UNKNOWN"))); + Log.d("compileShader: glslVersion = ", glslversion, ", type: ", (type == GL_VERTEX_SHADER ? "GL_VERTEX_SHADER" : (type == GL_FRAGMENT_SHADER ? "GL_FRAGMENT_SHADER" : "UNKNOWN"))); //Log.v("Shader code:\n", sourceCode); - GLuint shader = glCreateShader(type); + GLuint shader = checkgl!glCreateShader(type); const char * psrc = sourceCode.toStringz; - glShaderSource(shader, 1, &psrc, null); - glCompileShader(shader); + checkgl!glShaderSource(shader, 1, &psrc, null); + checkgl!glCompileShader(shader); GLint compiled; - glGetShaderiv(shader, GL_COMPILE_STATUS, &compiled); + checkgl!glGetShaderiv(shader, GL_COMPILE_STATUS, &compiled); if (compiled) { // compiled successfully return shader; } else { + Log.e("Failed to compile shader source:\n", sourceCode); GLint blen = 0; GLsizei slen = 0; - glGetShaderiv(shader, GL_INFO_LOG_LENGTH , &blen); + checkgl!glGetShaderiv(shader, GL_INFO_LOG_LENGTH , &blen); if (blen > 1) { GLchar[] msg = new GLchar[blen + 1]; - glGetShaderInfoLog(shader, blen, &slen, msg.ptr); - Log.d("Shader compilation error: ", fromStringz(msg.ptr)); + checkgl!glGetShaderInfoLog(shader, blen, &slen, msg.ptr); + Log.e("Shader compilation error: ", fromStringz(msg.ptr)); } return 0; } } bool compile() { - glslversion = std.string.fromStringz(cast(const char *)glGetString(GL_SHADING_LANGUAGE_VERSION)).dup; - + glslversion = checkgl!fromStringz(cast(const char *)glGetString(GL_SHADING_LANGUAGE_VERSION)).dup; glslversionString.length = 0; glslversionInt = 0; foreach(ch; glslversion) { @@ -212,6 +221,9 @@ class GLProgram : dlangui.graphics.scene.mesh.GraphicsEffect { } else if (ch != '.') break; } + version (Android) { + glslversionInt = 130; + } vertexShader = compileShader(vertexSource, GL_VERTEX_SHADER); fragmentShader = compileShader(fragmentSource, GL_FRAGMENT_SHADER); @@ -219,17 +231,17 @@ class GLProgram : dlangui.graphics.scene.mesh.GraphicsEffect { error = true; return false; } - program = glCreateProgram(); - glAttachShader(program, vertexShader); - glAttachShader(program, fragmentShader); - glLinkProgram(program); + program = checkgl!glCreateProgram(); + checkgl!glAttachShader(program, vertexShader); + checkgl!glAttachShader(program, fragmentShader); + checkgl!glLinkProgram(program); GLint isLinked = 0; - glGetProgramiv(program, GL_LINK_STATUS, &isLinked); + checkgl!glGetProgramiv(program, GL_LINK_STATUS, &isLinked); if (!isLinked) { GLint maxLength = 0; - glGetProgramiv(program, GL_INFO_LOG_LENGTH, &maxLength); + checkgl!glGetProgramiv(program, GL_INFO_LOG_LENGTH, &maxLength); GLchar[] msg = new GLchar[maxLength + 1]; - glGetProgramInfoLog(program, maxLength, &maxLength, msg.ptr); + checkgl!glGetProgramInfoLog(program, maxLength, &maxLength, msg.ptr); Log.e("Error while linking program: ", fromStringz(msg.ptr)); error = true; return false; @@ -1309,7 +1321,7 @@ class GLVertexBuffer : VertexBuffer { for(int i = 0; i < _format.length; i++) { int loc = effect.getVertexElementLocation(_format[i].type); if (loc >= 0) { - checkgl!glVertexAttribPointer(loc, _format[i].size, GL_FLOAT, GL_FALSE, _format.vertexSize, cast(char*)(offset)); + checkgl!glVertexAttribPointer(loc, _format[i].size, GL_FLOAT, cast(ubyte)GL_FALSE, _format.vertexSize, cast(char*)(offset)); checkgl!glEnableVertexAttribArray(loc); } else { //Log.d("Attribute location not found for ", _format[i].type); @@ -1402,7 +1414,7 @@ class DummyVertexBuffer : VertexBuffer { for(int i = 0; i < _format.length; i++) { int loc = effect.getVertexElementLocation(_format[i].type); if (loc >= 0) { - checkgl!glVertexAttribPointer(loc, _format[i].size, GL_FLOAT, GL_FALSE, _format.vertexSize, cast(char*)(offset)); + checkgl!glVertexAttribPointer(loc, _format[i].size, GL_FLOAT, cast(ubyte)GL_FALSE, _format.vertexSize, cast(char*)(offset)); checkgl!glEnableVertexAttribArray(loc); } else { //Log.d("Attribute location not found for ", _format[i].type); diff --git a/src/dlangui/platforms/common/startup.d b/src/dlangui/platforms/common/startup.d index f9a1ae34..122a40ff 100644 --- a/src/dlangui/platforms/common/startup.d +++ b/src/dlangui/platforms/common/startup.d @@ -222,6 +222,7 @@ extern (C) void initLogs() { } } else version(Android) { Log.setLogTag("dlangui"); + Log.setLogLevel(LogLevel.Trace); } else { Log.setStderrLogger(); }