This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

TDA2HG: [OpenGl] FBO:How to use glFramebufferTexture

Part Number: TDA2HG

Hello:

  On visionsdk 3.05, we use GL_TEXTURE_EXTERNAL_OES to import the NV12 image data, the OpenGl should operate on GL_TEXTURE_EXTERNAL_OES target.

for OpenGl framebuffer object(FBO)

  1. should we call glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_EXTERNAL_OES, m_stage_texture[i], 0) 
  2. or using glFramebufferTexture2DOES , when looking into the visionsdk source code we found 
1
glFramebufferTexture2DOES = (PFNGLFRAMEBUFFERTEXTURE2DOES)PVRGetProcAddress(glFramebufferTexture2DOES);

      in ./apps/src/hlos/modules/sgxRenderUtils/Tools/OGLES/PVRTglesExt.cpp.

so which is the right way  to use  glFramebufferTexture2D

  • Hi Andy,

    I don't have information on glFramebufferTexture2DOES support, I see this is a OPENGLES1 API and not supported with OPENGLES2.

    Thanks

    RamPrasad 

  • Hi RamPrasad :

      On visonSDK we use glEGLImageTargetTexture2DOES() to create texutre,  and operate on target GL_TEXTURE_EXTERNAL_OES.

    and now we use glFramebufferTexture(), when we call glFramebufferTexture(GL_TEXTURE_EXTERNAL_OES) will get an opengl error.

    so we wounder which is the right way to use the glFramebufferTexture

    
    

  • Hi andy,

    Can you share me what is the openGL error returned ?

    I will check the source code of sgx-um on what condition, it is returned.

    Thanks

    Ram

  • Hi Ram:
    Here are the source code

    // generate the framebuffer, renderbuffer, and texture object names for (i = 0; i < fbo_num; i++) { glGenFramebuffers(1, &(m_stage_fbo[i])); glGenRenderbuffers(1, &(m_stage_depth_render_buffer[i])); glGenTextures(1, &(m_stage_texture[i])); // andy TI support GL_TEXTURE_EXTERNAL_OES #ifdef APP_RUN_ON_TI //#define GL_TEXTURE_2D GL_TEXTURE_EXTERNAL_OES #endif // no texels need to be specified as we are going to draw into the texture glBindTexture(GL_TEXTURE_2D, m_stage_texture[i]); #if GLOBAL_RUN_ENV_DESKTOP == 0 && defined APP_RUN_ON_IMX6 // map addr to opengl viv (*g_pFNglTexDirectVIVMap)(GL_TEXTURE_2D, width, height, fbo_format, (void **)&(m_stage_fbo_vaddr[i]), (const GLuint *)(&m_stage_fbo_paddr[i])); #else glTexImage2D(GL_TEXTURE_EXTERNAL_OES, 0, fbo_format, width, height, 0, fbo_format, GL_UNSIGNED_BYTE, NULL); #endif glTexParameteri(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_MIN_FILTER, GL_LINEAR); // bind renderbuffer and create a 16-bit depth buffer // width and height of renderbuffer = width and height of // the texture glBindRenderbuffer(GL_RENDERBUFFER, m_stage_depth_render_buffer[i]); glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT16, width, height); // bind the framebuffer glBindFramebuffer(GL_FRAMEBUFFER, m_stage_fbo[i]); // specify texture as color attachment glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_EXTERNAL_OES, m_stage_texture[i], 0); eglCheckGlError("glFramebufferTexture2D"); printf("andy debug test glFramebufferTexture2D \n"); // specify depth_renderbufer as depth attachment glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, m_stage_depth_render_buffer[i]); // check for framebuffer complete GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER); if (status != GL_FRAMEBUFFER_COMPLETE) { AVMGPU_ERR("AvmGpu::avm_gpu_fbo_generate. framebuffer object %d is not complete\n", i); return 1; } } return 0;

    and we change all   GL_TEXTURE_2D  to GL_TEXTURE_EXTERNAL_OES.

    and the erros is :

    func:avm_gpu_fbo_generate line 1247 GL: after glFramebufferTexture2D() glError (0x502)
    andy debug test glFramebufferTexture2D 
    func:avm_gpu_fbo_generate line 1247 GL: after glFramebufferTexture2D() glError (0x502)
    andy debug test glFramebufferTexture2D 
    func:avm_gpu_fbo_generate line 1247 GL: after glFramebufferTexture2D() glError (0x502)
    andy debug test glFramebufferTexture2D 
    func:avm_gpu_fbo_generate line 1247 GL: after glFramebufferTexture2D() glError (0x502)
    andy debug test glFramebufferTexture2D 
    func:avm_gpu_fbo_generate line 1247 GL: after glFramebufferTexture2D() glError (0x502)
    andy debug test glFramebufferTexture2D 

    BTW we remember that glTexImage2D() is no supported on visionSDK, right?

  • Hi Ram:

    any update?

  • Hello,

    As you notice and as mentioned in the link below, GL_TEXTURE_EXTERNAL_OES cannot be used with glFrameBufferTexture2D:

    https://www.khronos.org/registry/OpenGL-Refpages/es2.0/xhtml/glFramebufferTexture2D.xml

    Can you please help us with defining your use case? Are you trying to render YUV? Or are you just trying to use the NV12 image as texture? If you can explain your use case, we will be able to help better.

    Regards

    Hemant

  • Hi Hemant:

    Hemant Hariyani said:
    Can you please help us with defining your use case?

    see the source code above, we want to render the yuv to framebuffer which can be reused. so we call glFramebufferTexture2D 

    if call glFramebufferTexture2D with GL_TEXTURE_2D , and no error but no image show up.

    as visionSDK use GL_TEXTURE_EXTERNAL_OES to import the yuv to texture, then we want to confirm should we use GL_TEXTURE_EXTERNAL_OES for 

    glFramebufferTexture2D , as you see there is an error, then should we use like this glFramebufferTexture2DOES = (PFNGLFRAMEBUFFERTEXTURE2DOES)PVRGetProcAddress(glFramebufferTexture2DOES);

  • Hi,

    To add additional observation, In the example snippet that was shared, the glTexImage2D() should have thrown an error had it been caught at that point as TEXTURE_EXTERNAL_OES target type cannot be used with that call. The reason is that glTexImage2D() call ensures that the texture is managed by the GPU but the TEXTURE_EXTERNAL_OES target is for externally allocated textures that are wrapped as EGLImages and hence the error you are seeing.

    If the intent is to use an EGLImage as an FBO, you can use the similar flow as you had but instead of calling glTexImage2D() you would have bind the EGLImage to the TEXTURE_2D target.

    Something like below

    in the setup you would create texture and framebuffer object and bind the framebuffer to the texture target

    glGenTextures(1, &tex_id)
    glBindTexture(GL_TEXTURE_2D, tex_id)
    glGenFramebuffers(1, &fbo)
    glBindFramebuffer(GL_FRAMEBUFFER, fbo)
    glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, tex_id, 0)

    in your draw call you would bind the eglimage to the texture 2d target. If there is no change in the eglimage in between draw calls you could do this in the setup call as well.

    glEGLImageTargetTexture2DOES(GL_TEXTURE_2D, eglImage)

    But do note that in the above the texture/EGLImage has to be RGBA format for it to be a valid fbo. The NV12 format is not supported as render surface as a consequence NV12 EGLImages cannot be framebuffer objects.

    Thanks,
    Gowtham

  • Hi Gowtham:

      Thanks, we will try it.

      Mark it as resolved.