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 (将#修改为@)

相关问答

依赖报错 idea导入项目后依赖报错,解决方案:https://blog....
错误1:代码生成器依赖和mybatis依赖冲突 启动项目时报错如下...
错误1:gradle项目控制台输出为乱码 # 解决方案:https://bl...
错误还原:在查询的过程中,传入的workType为0时,该条件不起...
报错如下,gcc版本太低 ^ server.c:5346:31: 错误:‘struct...