Cardboard View undistortTexture()无法正常工作以进行失真渲染

时间:2016-03-20 15:59:36

标签: android opengl-es google-cardboard

我正在尝试在我的一个基于OpenGL的应用程序中使用Cardboard Android SDK来构建VR体验。

为此,我正在关注google的pie-noon项目。我正在尝试使用undistortTexture()类的函数CardboardView来应用最终失真。此函数将GLuint作为纹理ID,使用渲染到纹理技术进行渲染。

我已做了相应的一切,但由于某些原因,只出现黑屏。

以下是我的代码

帧缓冲区的初始化

GL_CALL(glGenTextures(1, &g_undistort_texture_id));
GL_CALL(glBindTexture(GL_TEXTURE_2D, g_undistort_texture_id));
GL_CALL(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE));
GL_CALL(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE));
GL_CALL(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR));
GL_CALL(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR));
GL_CALL(glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, nullptr));

GL_CALL(glGenRenderbuffers(1, &g_undistort_renderbuffer_id));
GL_CALL(glBindRenderbuffer(GL_RENDERBUFFER, g_undistort_renderbuffer_id));
GL_CALL(glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT16, width,
                              height));

GL_CALL(glGenFramebuffers(1, &g_undistort_framebuffer_id));
GL_CALL(glBindFramebuffer(GL_FRAMEBUFFER, g_undistort_framebuffer_id));

GL_CALL(glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, g_undistort_texture_id, 0));
GL_CALL(glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER,
                                  g_undistort_renderbuffer_id));

GL_CALL(glBindFramebuffer(GL_FRAMEBUFFER, 0));


if(glCheckFramebufferStatus(GL_FRAMEBUFFER) == GL_FRAMEBUFFER_COMPLETE){
    EXAMPLE_LOG("GLDEBUG::: New Frame Buffer is Complete");
}else{
    EXAMPLE_LOG("GLDEBUG::: New Frame Buffer is NOT Complete");
}

渲染和失真代码

// swap buffers
GL_CALL(eglSwapBuffers(m_displayService.GetDisplay(), m_displayService.GetSurface()));

// clear buffers
GLHelpers::ClearBuffers();

// bind your render to texture frame buffer
glBindFramebuffer(GL_FRAMEBUFFER, m_displayService.GetFrameBufferId());

// engine draw call
app->Draw(deltaSeconds);

// bind back default frame buffer
glBindFramebuffer(GL_FRAMEBUFFER, 0);

// set viewport back to full screen from steroscopic viewport for VR
glViewport(0, 0, m_displayService.GetDisplayWidth()*2.f, m_displayService.GetDisplayHeight());

// jni call to "UndistortTexture()" function of MainActivity which contains CardboardView and calls cardboard view's undistortTexture()
JNIEnv* env = m_pNativeState->mainThreadEnv;
jobject activity = m_pNativeState->activity;
jclass fpl_class = env->GetObjectClass(activity);
jmethodID undistort = env->GetMethodID(fpl_class, "UndistortTexture", "(I)V");
env->CallVoidMethod(activity, undistort, (jint)m_displayService.GetTextureId());
env->DeleteLocalRef(fpl_class);

以下是JNI调用的Java函数

public void UndistortTexture(int textureId){
    try {
            m_cardboardView.undistortTexture(textureId);
        } catch (Exception e) {
          Log.e("backgroundThreadActivity", "exception", e);
        }
}

创建Surfaceview后,我按照以下更新屏幕参数

public void SetHeadMountedDisplayResolution(int width, int height) {

    try {
        if (m_cardboardView == null)
            return;

        Display display = getWindowManager().getDefaultDisplay();
        ScreenParams sp = new ScreenParams(display);
        Phone.PhoneParams pp = new Phone.PhoneParams();
        pp.setXPpi(width / sp.getWidthMeters() * METERS_PER_INCH);
        pp.setYPpi(height / sp.getHeightMeters() * METERS_PER_INCH);
        sp = ScreenParams.fromProto(display, pp);

        sp.setWidth(width);
        sp.setHeight(height);
        m_cardboardView.updateScreenParams(sp);

    } catch (Exception e) {
        Log.e("backgroundThreadActivity", "exception", e);
    }
}

0 个答案:

没有答案