2013-10-08 66 views
0

我們正在開發用於幻燈片創建和使用OpenGL的軟件。 我們使用FBO + PBO用於快速數據從VGA讀取到RAM,但在從ATI一些顯卡,我們面臨以下問題:OpenGL + PBO + FBO +一些ATI卡 - 顏色和像素移位

  1. 交換RGB分量
  2. 像素移動

有如果我們不使用PBO,沒有問題。 我們也注意到,PBO/FBO(4:3)的長寬比解決了像素偏移問題。

任何想法或建議?

以下是詳細信息:

  • 的ATI Radeon HD 3650

PBO代碼:

public bool PBO_Initialize(
     int bgl_size_w, 
     int bgl_size_h) 
    { 
     PBO_Release(); 
     if (mCSGL12Control1 != null) 
     { 
      GL mGL = mCSGL12Control1.GetGL(); 
      mCSGL12Control1.wgl_MakeCurrent(); 
      // 
      // check PBO is supported by your video card 
      if (mGL.bglGenBuffersARB == true && 
       mGL.bglBindBufferARB == true && 
       mGL.bglBufferDataARB == true && 
       mGL.bglBufferSubDataARB == true && 
       mGL.bglMapBufferARB == true && 
       mGL.bglUnmapBufferARB == true && 
       mGL.bglDeleteBuffersARB == true && 
       mGL.bglGetBufferParameterivARB == true) 
      { 
       mGL.glGenBuffersARB(2, _pbo_imageBuffers); 
       int clientHeight1 = bgl_size_h/2; 
       int clientHeight2 = bgl_size_h - clientHeight1; 
       int clientSize1 = bgl_size_w * clientHeight1 * 4; 
       int clientSize2 = bgl_size_w * clientHeight2 * 4; 


       mGL.glBindBufferARB(GL.GL_PIXEL_PACK_BUFFER_ARB, _pbo_imageBuffers[0]); 
       mGL.glBufferDataARB(GL.GL_PIXEL_PACK_BUFFER_ARB, clientSize1, IntPtr.Zero, 
           GL.GL_STREAM_READ_ARB); 

       mGL.glBindBufferARB(GL.GL_PIXEL_PACK_BUFFER_ARB, _pbo_imageBuffers[1]); 
       mGL.glBufferDataARB(GL.GL_PIXEL_PACK_BUFFER_ARB, clientSize2, IntPtr.Zero, 
           GL.GL_STREAM_READ_ARB); 

       return true; 
      } 
     } 
     return false; 
    } 

... PBO讀取數據回內存

    int clientHeight1 = _bgl_size_h/2; 
        int clientHeight2 = _bgl_size_h - clientHeight1; 
        int clientSize1 = _bgl_size_w * clientHeight1 * 4; 
        int clientSize2 = _bgl_size_w * clientHeight2 * 4; 
        //mGL.glPushAttrib(GL.GL_VIEWPORT_BIT | GL.GL_COLOR_BUFFER_BIT); 

        // Bind two different buffer objects and start the glReadPixels 
        // asynchronously. Each call will return directly after 
        // starting the DMA transfer. 
        mGL.glBindBufferARB(GL.GL_PIXEL_PACK_BUFFER_ARB, _pbo_imageBuffers[0]); 
        mGL.glReadPixels(0, 0, _bgl_size_w, clientHeight1, imageFormat, 
            pixelTransferMethod, IntPtr.Zero); 

        mGL.glBindBufferARB(GL.GL_PIXEL_PACK_BUFFER_ARB, _pbo_imageBuffers[1]); 
        mGL.glReadPixels(0, clientHeight1, _bgl_size_w, clientHeight2, imageFormat, 
            pixelTransferMethod, IntPtr.Zero); 

        //mGL.glPopAttrib(); 
        mGL.glBindFramebufferEXT(GL.GL_FRAMEBUFFER_EXT, 0); 

        // Process partial images. Mapping the buffer waits for 
        // outstanding DMA transfers into the buffer to finish. 
        mGL.glBindBufferARB(GL.GL_PIXEL_PACK_BUFFER_ARB, _pbo_imageBuffers[0]); 
        IntPtr pboMemory1 = mGL.glMapBufferARB(GL.GL_PIXEL_PACK_BUFFER_ARB, 
               GL.GL_READ_ONLY_ARB); 

        mGL.glBindBufferARB(GL.GL_PIXEL_PACK_BUFFER_ARB, _pbo_imageBuffers[1]); 
        IntPtr pboMemory2 = mGL.glMapBufferARB(GL.GL_PIXEL_PACK_BUFFER_ARB, 
               GL.GL_READ_ONLY_ARB); 


        System.Runtime.InteropServices.Marshal.Copy(pboMemory1, _bgl_rgbaData_out, 0, clientSize1); 
        System.Runtime.InteropServices.Marshal.Copy(pboMemory2, _bgl_rgbaData_out, clientSize1, clientSize2); 


        // Unmap the image buffers 
        mGL.glBindBufferARB(GL.GL_PIXEL_PACK_BUFFER_ARB, _pbo_imageBuffers[0]); 
        mGL.glUnmapBufferARB(GL.GL_PIXEL_PACK_BUFFER_ARB); 
        mGL.glBindBufferARB(GL.GL_PIXEL_PACK_BUFFER_ARB, _pbo_imageBuffers[1]); 
        mGL.glUnmapBufferARB(GL.GL_PIXEL_PACK_BUFFER_ARB); 

FBO初始化

private static void FBO_Initialize(GL mGL, 
     ref int[] bgl_texture, 
     ref int[] bgl_framebuffer, 
     ref int[] bgl_renderbuffer, 
     ref byte[] bgl_rgbaData, 
     int bgl_size_w, 
     int bgl_size_h) 
    { 
     // Texture 
     mGL.glGenTextures(1, bgl_texture); 
     mGL.glBindTexture(GL.GL_TEXTURE_2D, bgl_texture[0]); 

     mGL.glTexParameteri(GL.GL_TEXTURE_2D, GL.GL_TEXTURE_MAG_FILTER, GL.GL_NEAREST); 
     mGL.glTexParameteri(GL.GL_TEXTURE_2D, GL.GL_TEXTURE_MIN_FILTER, GL.GL_NEAREST); 
     mGL.glTexParameteri(GL.GL_TEXTURE_2D, GL.GL_TEXTURE_WRAP_S, GL.GL_CLAMP_TO_EDGE); 
     mGL.glTexParameteri(GL.GL_TEXTURE_2D, GL.GL_TEXTURE_WRAP_T, GL.GL_CLAMP_TO_EDGE); 
     IntPtr null_ptr = new IntPtr(0); 
     // <null> means reserve texture memory, but texels are undefined 
     mGL.glTexImage2D(GL.GL_TEXTURE_2D, 0, GL.GL_RGBA, bgl_size_w, bgl_size_h, 0, GL.GL_RGBA, GL.GL_UNSIGNED_BYTE, null_ptr); 
     // 
     mGL.glGenFramebuffersEXT(1, bgl_framebuffer); 
     mGL.glBindFramebufferEXT(GL.GL_FRAMEBUFFER_EXT, bgl_framebuffer[0]); 

     mGL.glGenRenderbuffersEXT(1, bgl_renderbuffer); 
     mGL.glBindRenderbufferEXT(GL.GL_RENDERBUFFER_EXT, bgl_renderbuffer[0]); 
     mGL.glRenderbufferStorageEXT(GL.GL_RENDERBUFFER_EXT, GL.GL_DEPTH_COMPONENT24, bgl_size_w, bgl_size_h); 


     mGL.glFramebufferTexture2DEXT(GL.GL_FRAMEBUFFER_EXT, GL.GL_COLOR_ATTACHMENT0_EXT, 
      GL.GL_TEXTURE_2D, bgl_texture[0], 0); 
     mGL.glFramebufferRenderbufferEXT(GL.GL_FRAMEBUFFER_EXT, GL.GL_DEPTH_ATTACHMENT_EXT, 
      GL.GL_RENDERBUFFER_EXT, bgl_renderbuffer[0]); 

     // Errors? 
     int status = mGL.glCheckFramebufferStatusEXT(GL.GL_FRAMEBUFFER_EXT); 
     if (status != GL.GL_FRAMEBUFFER_COMPLETE_EXT || mGL.glGetError() != GL.GL_NO_ERROR) 
     { 
      mGL.glFramebufferTexture2DEXT(GL.GL_FRAMEBUFFER_EXT, GL.GL_COLOR_ATTACHMENT0_EXT, 
       GL.GL_TEXTURE_2D, 0, 0); 
      mGL.glFramebufferRenderbufferEXT(GL.GL_FRAMEBUFFER_EXT, GL.GL_DEPTH_ATTACHMENT_EXT, 
       GL.GL_RENDERBUFFER_EXT, 0); 

      mGL.glBindTexture(GL.GL_TEXTURE_2D, 0); 
      mGL.glDeleteTextures(1, bgl_texture); 
      mGL.glBindRenderbufferEXT(GL.GL_RENDERBUFFER_EXT, 0); 
      mGL.glDeleteRenderbuffersEXT(1, bgl_renderbuffer); 
      mGL.glBindFramebufferEXT(GL.GL_FRAMEBUFFER_EXT, 0); 
      mGL.glDeleteFramebuffersEXT(1, bgl_framebuffer); 

      throw new Exception("Bad framebuffer."); 
     } 

     mGL.glDrawBuffer(GL.GL_COLOR_ATTACHMENT0_EXT); 
     mGL.glReadBuffer(GL.GL_COLOR_ATTACHMENT0_EXT); // For glReadPixels() 

     mGL.glBindFramebufferEXT(GL.GL_FRAMEBUFFER_EXT, 0); 

     mGL.glDrawBuffer(GL.GL_BACK); 
     mGL.glReadBuffer(GL.GL_BACK); 
     mGL.glBindTexture(GL.GL_TEXTURE_2D, 0); 

     bgl_rgbaData = new byte[bgl_size_w * bgl_size_h * 4]; 
    } 

enter image description here

+0

如果沒有看到您的代碼,我們無法幫助您。有很多可能的原因。 – derhass

+0

Thx,已更新信息 – okarpov

+1

您是否有任何理由特別使用EXT FBO擴展? Radeon HD 3xxx硬件支持OpenGL 3.2,EXT擴展是一個沒有維護的混亂,你應該使用ARB或核心OpenGL 3.0 FBO。同樣,公益組織也是核心。我首先將代碼遷移到首先使用核心OpenGL,然後看看是否改變了任何東西;如果事實證明這是一個擴展互操作,你可能需要編寫多個代碼路徑。 AMD硬件問題。 –

回答

2

看來,重新安裝/升級VGA驅動程序解決了這個問題。

真的很奇怪的行爲(也可能是官方的筆記本驅動程序是舊的/ buggy /等等,導致這個問題,所以用AMD最新的驅動程序更新這個vga芯片系列,似乎影響/解決問題,另外我不確定previouse驅動是否設置正確,因此我說重新安裝/更新)

謝謝大家的幫助。