How to force landscape mode using NDK to use pure C ++ codes

in general, it works fine. but if I lock the screen and wait for APP_CMD_LOST_FOCUS, then I unlock srceen. he changes to a portrait! but I find that egl buff is still set to landscape, and all coordinates are larger.

my installation of AndroidManifest.xml:

<activity android:name="android.app.NativeActivity" android:theme="@android:style/Theme.NoTitleBar.Fullscreen" android:configChanges="orientation|keyboardHidden" android:screenOrientation="landscape" android:clearTaskOnLaunch="true"> <meta-data android:name="android.app.lib_name" android:value="sunred" /> <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> 

my egl init C ++ code

 int engine_init_display(OSCONTEXTENGINE* pEngine, const DISPLAY_CONFIG* pConfig) { // initialize OpenGL ES and EGL /* * 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 attribs[] = { EGL_SURFACE_TYPE, EGL_WINDOW_BIT, EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT, EGL_BLUE_SIZE, 8, EGL_GREEN_SIZE, 8, EGL_RED_SIZE, 8, EGL_DEPTH_SIZE, 8, EGL_NONE }; EGLint w, h, dummy, format; EGLint numConfigs; EGLConfig config; EGLSurface surface; EGLContext context; EGLDisplay display = eglGetDisplay(EGL_DEFAULT_DISPLAY); eglInitialize(display, 0, 0); //eglBindAPI(EGL_OPENGL_ES_API); /* Here, the application chooses the configuration it desires. In this * sample, we have a very simplified selection process, where we pick * the first EGLConfig that matches our criteria */ EGLBoolean bres = eglChooseConfig(display, attribs, &config, 1, &numConfigs); if (!bres) { __android_log_print(LOGINFO_ERROR, "engine_init_display", "numConfigs = %d", numConfigs); } /* EGL_NATIVE_VISUAL_ID is an attribute of the EGLConfig that is * guaranteed to be accepted by ANativeWindow_setBuffersGeometry(). * As soon as we picked a EGLConfig, we can safely reconfigure the * ANativeWindow buffers to match, using EGL_NATIVE_VISUAL_ID. */ eglGetConfigAttrib(display, config, EGL_NATIVE_VISUAL_ID, &format); ANativeWindow_setBuffersGeometry(pEngine->m_app->window, 0, 0, format); surface = eglCreateWindowSurface(display, config, pEngine->m_app->window, NULL); const EGLint ai32ContextAttribs[] = { EGL_CONTEXT_CLIENT_VERSION, 2, EGL_NONE }; context = eglCreateContext(display, config, NULL, ai32ContextAttribs); if (eglMakeCurrent(display, surface, surface, context) == EGL_FALSE) { LOGW("Unable to eglMakeCurrent"); return P_ERR; } eglQuerySurface(display, surface, EGL_WIDTH, &w); eglQuerySurface(display, surface, EGL_HEIGHT, &h); pEngine->m_EglDisplay = display; pEngine->m_EglContext = context; pEngine->m_EglSurface = surface; pEngine->m_iWidth = w; pEngine->m_iHeight = h; return 0; } 

when APP_CMD_INIT_WINDOW happens, I call engine_init_display.

Is there any way to get it to use C ++ in landscape mode?

rendering frame:

works fine:

 pEngine->m_iWidth = 960; pEngine->m_iHeight = 540; 

lock screeen → APP_CMD_LOST_FOCUS → unlock screen

 pEngine->m_iWidth = 540; pEngine->m_iHeight = 960; 

windows change to a portrait! but egl buff is still set up for the landscape, and all coordinates are larger.

+4
source share
2 answers

When you get APP_CMD_CONFIG_CHANGED, try another init:

  case APP_CMD_CONFIG_CHANGED: if (engine->app->window != NULL && ((engine->width != ANativeWindow_getWidth(app->window)) || (engine->height != ANativeWindow_getHeight(app->window)))) { engine_handle_cmd(app, APP_CMD_TERM_WINDOW); engine_handle_cmd(app, APP_CMD_INIT_WINDOW); } break; 

(Variable names, etc. from the NativeActivity example code.) In the end, you will go through init several times after waking up; if this is a problem, you can also do lazy init and just invalidate the configuration in both APP_CMD_CONFIG_CHANGED and APP_CMD_INIT_WINDOW.

This is from live code; in our testing, it works in about 99% of cases in 2.3 and later versions (previously unverified), but a very small amount of time starting the program from the lock screen and then unlocking causes a race state when CONFIG_CHANGED is not called and we wake up, stuck in the landscape. For our game, this is not the way of the user code (launching from the lock screen), so I have not explored yet.

+1
source

If someone is still interested in a clean native solution for setting the requested screen orientation / activity, use the code below.

For more information on the associated JAVA method:

https://developer.android.com/reference/android/app/Activity.html#setRequestedOrientation(int)

 void set_requested_screen_orientation(struct android_app * app, int an_orientation){ JNIEnv * jni; app->activity->vm->AttachCurrentThread(&jni, NULL); jclass clazz = jni->GetObjectClass(app->activity->clazz); jmethodID methodID = jni->GetMethodID(clazz, "setRequestedOrientation", "(I)V"); jni->CallVoidMethod(app->activity->clazz, methodID, an_orientation); app->activity->vm->DetachCurrentThread(); } 
0
source

Source: https://habr.com/ru/post/1437514/


All Articles