C ++ EGL使用PBuffer表面渲染为纹理

问题描述

我正在尝试渲染到纹理,然后绘制纹理。首先,我尝试使用帧缓冲区对象来完成此操作,但是我无法glGenFrameBuffers()给我一个有效的帧缓冲区对象。大约一年前,我在这里发布了一个问题:EGL/OpenGLES glGenFramebuffers not working with Native Android Project in VS 2019

经过进一步研究,我了解了EGL PBuffer Surface对象。因此,我尝试使用一些参考来拼凑出一些可行的方法。但是,我仍然无法渲染纹理以使用PBuffer对象。我要遵循的主要示例如下:https://processors.wiki.ti.com/index.php/Render_to_Texture_with_OpenGL_ES

我创建了一个rendertarget类,以更轻松地管理渲染目标。除了调用eglBindTexImage()以外,其他一切似乎都正常。它返回FALSE错误EGL_BAD_disPLAY。我给它一个与所有其他API调用相同的EGLdisplay对象,该对象是从eglGetCurrentdisplay()获取的,通常具有0x1的值。

我正在使用m_pdisplay类中的有效Engine运行整个应用程序。

这是我的代码

void rendertarget::CreateSurfaceTarget(EGLConfig i_pConfig,GLfloat i_fWidth,GLfloat i_fheight)
{
    EGLdisplay pCurdisplay  = eglGetCurrentdisplay();
    EGLContext pCurContext  = eglGetCurrentContext();
    EGLSurface pPrevSurface = eglGetCurrentSurface(EGL_DRAW);
    m_fWidth    = i_fWidth;
    m_fheight   = i_fheight;
    
    createEglConfig(pCurdisplay,i_pConfig);
    if (m_pEglConfig)
    {
        EGLint attr[] =
        {
            EGL_WIDTH,static_cast<EGLint>(i_fWidth),EGL_HEIGHT,static_cast<EGLint>(i_fheight),EGL_TEXTURE_TARGET,EGL_TEXTURE_2D,EGL_TEXTURE_FORMAT,EGL_TEXTURE_RGBA,EGL_NONE
        };

        m_pSurface = eglCreatePbufferSurface(pCurdisplay,m_pEglConfig,attr);
        if (m_pSurface)
        {
            createTexture();

            eglMakeCurrent(pCurdisplay,m_pSurface,pCurContext);
            eglBindTexImage(pCurdisplay,EGL_BACK_BUFFER); // <--- THIS RETURNS FALSE WITH ERROR 'EGL_BAD_disPLAY'
            eglMakeCurrent(pCurdisplay,pPrevSurface,pCurContext);
            glBindTexture(GL_TEXTURE_2D,0);
        }
        else
            ENGINE_LOGE("rendertarget::CreateSurfaceTarget() - Failed to create a PBuffer Surface");
    }
}
void rendertarget::BindTarget(EGLdisplay i_pdisplay,EGLContext i_pContext)
{
    if (eglMakeCurrent(i_pdisplay,i_pContext))
    {
        glViewport(0,m_fWidth,m_fheight);
        glBindTexture(GL_TEXTURE_2D,m_nTexID);
    }
}
void rendertarget::UnbindTarget(EGLdisplay i_pdisplay,EGLContext i_pContext,EGLSurface i_pPrevSurface)
{
    eglreleaseTexImage(i_pdisplay,EGL_BACK_BUFFER);
    eglBindTexImage(i_pdisplay,EGL_BACK_BUFFER);
    eglMakeCurrent(i_pdisplay,i_pPrevSurface,i_pContext);
    glBindTexture(GL_TEXTURE_2D,0);
}
void rendertarget::createEglConfig(EGLdisplay i_pdisplay,EGLConfig i_pMainConfig)
{
    EGLint configAttr[] =
    {
        //EGL_RENDERABLE_TYPE,EGL_OPENGL_ES2_BIT,EGL_CONfig_CAVEAT,EGL_NONE,EGL_RED_SIZE,8,EGL_GREEN_SIZE,EGL_BLUE_SIZE,EGL_ALPHA_SIZE,//EGL_BUFFER_SIZE,32,// RGBA = 32 bits
        EGL_SURFACE_TYPE,EGL_PBUFFER_BIT,// We want a PBuffer
        EGL_BIND_TO_TEXTURE_RGBA,EGL_TRUE,EGL_NONE
    };

    EGLint nNumConfigs;
    if (!eglChooseConfig(i_pdisplay,configAttr,&m_pEglConfig,1,&nNumConfigs) || nNumConfigs != 1)
        ENGINE_LOGE("rendertarget::rendertarget() - Failed to create EGLConfig");
}
void rendertarget::Render(PosType i_fX,PosType i_fY)
{
    if (m_nTexID)
    {
        // Bind Vertices,TexCoords,and Texture
        glVertexPointer(3,GL_FLOAT,m_Quad.Vertices);
        glTexCoordPointer(2,m_TexCoord);
        glColor4f(m_Color[0],m_Color[1],m_Color[2],m_Color[3]);
        glBindTexture(GL_TEXTURE_2D,m_nTexID);

        // Set position and Draw
        glPushmatrix();
        glTranslatef(i_fX,i_fY,0.0f);
        glDrawArrays(GL_TRIANGLES,m_Quad.nNumVerts);
        glPopMatrix();

        // Unbind the texture
        glBindTexture(GL_TEXTURE_2D,0);
    }
}

这是我的使用方式

bool Engine::Init()
{
    initwindow();
    initOpenGL();

    /*
        APPLICATION STUFF...
    */

    pTarget = new rendertarget();
    pTarget->CreateSurfaceTarget(m_pEglConfig,300.0f,300.0f);
}
void Engine::Draw()
{
    if (m_pdisplay != EGL_NO_disPLAY)
    {
        GLint curViewportSize[4];
        glGetIntegerv(GL_VIEWPORT,curViewportSize);

        pTarget->BindTarget(m_pdisplay,m_pContext);

        glColor4f(1.0f,1.0f,1.0f);
        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

        pTarget->UnbindTarget(m_pdisplay,m_pContext,m_pSurface);

        glViewport(curViewportSize[0],curViewportSize[1],curViewportSize[2],curViewportSize[3]);
        pTarget->Render(10,10);

        eglSwapBuffers(m_pdisplay,m_pSurface);
    }
}

这就是我初始化EGL / OpenGL的方式

bool Engine::initwindow()
{
    m_pdisplay = eglGetdisplay(EGL_DEFAULT_disPLAY));
    eglInitialize(m_pdisplay,0);
    eglChooseConfig(m_pdisplay,attribs,&nNumConfigs);
    eglGetConfigAttrib(m_pdisplay,EGL_NATIVE_VISUAL_ID,&nFormat);

    ANativeWindow_setBuffersGeometry(m_pApp->window,nFormat);
    m_pSurface = eglCreateWindowSurface(m_pdisplay,m_pApp->window,nullptr);
    m_pContext = eglCreateContext(m_pdisplay,nullptr,nullptr);
    eglMakeCurrent(m_pdisplay,m_pContext);

    eglQuerySurface(m_pdisplay,EGL_WIDTH,&m_nWidth);
    eglQuerySurface(m_pdisplay,&m_nHeight);
}

bool Engine::initOpenGL()
{
    glHint(GL_PERSPECTIVE_CORRECTION_HINT,GL_FASTEST);
    glShadeModel(GL_SMOOTH);
    glEnable(GL_CULL_FACE);
    glEnable(GL_TEXTURE_2D);
    glEnable(GL_BLEND);
    gldisable(GL_DEPTH_TEST);
    glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);
    glEnableClientState(GL_VERTEX_ARRAY);
    glEnableClientState(GL_TEXTURE_COORD_ARRAY);
    glClearColor(1.0f,0.41f,0.71f,1.0f);
    glLoadIdentity();
    glOrthof(0,m_nWidth,m_nHeight,10);
}

我希望屏幕上会显示300x300的纯白色纹理,但我什么也没得到。有什么想法吗?

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)