【问题标题】:how to force landscape mode with NDK using pure c++ codes如何使用纯 C++ 代码使用 NDK 强制横向模式
【发布时间】:2012-10-03 06:20:17
【问题描述】:

一般来说,它工作正常。但如果我锁定屏幕,并等待 APP_CMD_LOST_FOCUS 发生,然后我解锁屏幕。它变成肖像!但我发现 egl buff 仍然是横向设置,并且所有坐标都更大。

我的 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>

我的 egl 初始化 c++ 代码

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;
}

当APP_CMD_INIT_WINDOW发生时,我调用engine_init_display。

有什么方法可以强制使用 c++ 将其设置为横向模式吗?

渲染帧:

工作正常:

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

锁屏 -> APP_CMD_LOST_FOCUS -> 解锁屏幕

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

窗口变为纵向! 但是egl buff还是横向设置,所有坐标都比较大。

【问题讨论】:

    标签: android opengl-es android-ndk opengl-es-2.0


    【解决方案1】:

    当您获得 APP_CMD_CONFIG_CHANGED 后,尝试进行另一个初始化:

        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;
    

    (NativeActivity 示例代码中的变量名称等。)您最终会在唤醒时经历多次初始化;如果这是一个问题,你也可以做惰性初始化,只是使 APP_CMD_CONFIG_CHANGED 和 APP_CMD_INIT_WINDOW 中的配置无效。

    这是来自实时代码;在我们的测试中,它在 2.3 及更高版本中大约 99% 的时间都有效(之前未经测试),但在极少数情况下从锁定屏幕启动程序然后解锁会导致不调用 CONFIG_CHANGED 的竞争条件我们醒来时被困在风景中。对于我们的游戏,这不是用户代码路径(从锁定屏幕启动),所以我没有进一步调查。

    【讨论】:

      【解决方案2】:

      如果有人仍然对设置请求的屏幕/活动方向的纯原生解决方案感兴趣,请使用下面的代码。

      有关相关 JAVA 方法的更多信息:

      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();
      
      }
      

      【讨论】:

        猜你喜欢
        • 2011-01-10
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-06-15
        • 2015-06-23
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多