2013-10-08 7 views
0

우리는 슬라이드 쇼 생성 용 소프트웨어를 개발 중이며 OpenGL을 사용하고 있습니다. 우리는 RAM에 VGA에서 읽기 빠른 데이터에 대한 FBO + PBO를 사용하지만 ATI에서 일부 비디오 카드에 우리는 다음과 같은 문제에 직면 :OpenGL + PBO + FBO + 일부 ATI 카드 - 색상 및 픽셀 이동

  1. 교환 RGB 구성 요소
  2. 픽셀이

이 있습니다 이동 우리가 PBO를 사용하지 않는다면 문제 없습니다. 또한 PBO/FBO (4 : 3)의 종횡비가 픽셀 이동 문제를 해결한다는 것을 알았습니다.

의견이나 제안이 있으십니까? 여기

더 자세한 사항은 다음과 같습니다 HD

  • ATI 라데온 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를 사용할 수있을 때마다 사용해야합니다. 마찬가지로 PBO도 핵심입니다. 핵심 OpenGL을 먼저 사용하도록 코드를 마이그레이션하고 우선 변경 사항을 확인하십시오. 확장 interop 인 경우 여러 코드 경로를 작성해야 할 수도 있습니다. AMD 하드웨어 문제. –

답변

2

그 다시 설치/VGA 드라이버를 업데이트하여이 문제를 해결하지 보인다.

비정상적인 동작 (또한 공식 노트북 드라이버가 오래된/버그/등등이 문제 일 수 있으므로이 vga 칩 시리즈의 경우 AMD의 최신 드라이버로 업데이트하면 영향을 미칩니다/해결) 문제는. 또한 전 운전사 드라이버가 올바르게 설치되었는지 다시 모르겠다. 다시 설치/업데이트라고 말하면된다.)

고맙습니다.