2013-10-17 7 views
1

OpenGL을 사용하여 RGB 프레임을 렌더링하려고합니다. 메모리가 CPU에 할당되면 코드가 정상적으로 작동합니다. 그러나, 내가 픽셀 버퍼 객체의 개념을 사용하여 GPU에 메모리를 할당하면 프레임을 렌더링하는 동안 문제가 발생합니다.OpenGL PBO가 nVidia 그래픽 카드에서 작동하지 않습니다.

문제는 표시창이 완전히 흰색이라는 것입니다. 다른 그래픽 카드에서 동일한 코드가 실행되면 코드가 정상적으로 작동합니다. 그러나 nVidia 그래픽 카드가있는 시스템에서 실행할 때이 흰색 화면 문제가 발생합니다.

glMapBufferARB이 주소를 반환하면 내가 디버깅 및 검사 한
#include <stdio.h> 
#include <stdlib.h> 
#include "glew.h" 
#include "glfw.h" 
#include "glaux.h" 

PFNGLGENBUFFERSARBPROC pglGenBuffersARB = 0;      // VBO Name Generation Procedure 
PFNGLBINDBUFFERARBPROC pglBindBufferARB = 0;      // VBO Bind Procedure 
PFNGLBUFFERDATAARBPROC pglBufferDataARB = 0;      // VBO Data Loading Procedure 
PFNGLBUFFERSUBDATAARBPROC pglBufferSubDataARB = 0;    // VBO Sub Data Loading Procedure 
PFNGLDELETEBUFFERSARBPROC pglDeleteBuffersARB = 0;    // VBO Deletion Procedure 
PFNGLGETBUFFERPARAMETERIVARBPROC pglGetBufferParameterivARB = 0; // return various parameters of VBO 
PFNGLMAPBUFFERARBPROC pglMapBufferARB = 0;      // map VBO procedure 
PFNGLUNMAPBUFFERARBPROC pglUnmapBufferARB = 0;     // unmap VBO procedure 
#define glGenBuffersARB   pglGenBuffersARB 
#define glBindBufferARB   pglBindBufferARB 
#define glBufferDataARB   pglBufferDataARB 
#define glBufferSubDataARB  pglBufferSubDataARB 
#define glDeleteBuffersARB  pglDeleteBuffersARB 
#define glGetBufferParameterivARB pglGetBufferParameterivARB 
#define glMapBufferARB   pglMapBufferARB 
#define glUnmapBufferARB   pglUnmapBufferARB 

int index; 
int pboSupported; 
int pboMode; 
GLuint pixBuffObjs[2]; 
HDC hDC = NULL; 
GLuint texture; 
char *FileName; 
unsigned char *guibuffer; 
AUX_RGBImageRec texture1; 
unsigned long long pos=0; 
GLuint myPBO; 


void initGL(void) 
{ 
     int maxSz; 
     int maxwidth = 416; 
     int maxheight = 240; 

     if(!glfwInit()) 
     { 
      exit(EXIT_FAILURE); 
     } 


     // if(!glfwOpenWindow(4096, 2118, 0,0,0,0,0,0, GLFW_WINDOW)) 
     if(!glfwOpenWindow(maxwidth, maxheight, 0,0,0,0,0,0, GLFW_WINDOW )) //GLFW_FULLSCREEN 
     { 
      glfwTerminate(); 
      exit(EXIT_FAILURE); 
     } 

     glfwSetWindowTitle("sample"); 

     glGenBuffersARB = (PFNGLGENBUFFERSARBPROC)wglGetProcAddress("glGenBuffersARB"); 
     glBindBufferARB = (PFNGLBINDBUFFERARBPROC)wglGetProcAddress("glBindBufferARB"); 
     glBufferDataARB = (PFNGLBUFFERDATAARBPROC)wglGetProcAddress("glBufferDataARB"); 
     glBufferSubDataARB = (PFNGLBUFFERSUBDATAARBPROC)wglGetProcAddress("glBufferSubDataARB"); 
     glDeleteBuffersARB = (PFNGLDELETEBUFFERSARBPROC)wglGetProcAddress("glDeleteBuffersARB"); 
     glGetBufferParameterivARB = (PFNGLGETBUFFERPARAMETERIVARBPROC)wglGetProcAddress("glGetBufferParameterivARB"); 
     glMapBufferARB = (PFNGLMAPBUFFERARBPROC)wglGetProcAddress("glMapBufferARB"); 
     glUnmapBufferARB = (PFNGLUNMAPBUFFERARBPROC)wglGetProcAddress("glUnmapBufferARB"); 

     // check once again PBO extension 
     if(glGenBuffersARB && glBindBufferARB && glBufferDataARB && glBufferSubDataARB && 
      glMapBufferARB && glUnmapBufferARB && glDeleteBuffersARB && glGetBufferParameterivARB) 
     { 
      pboSupported = 1; 
      pboMode = 1; // using 1 PBO 
      printf("Video card supports GL_ARB_pixel_buffer_object."); 
      glGenBuffersARB(1, &pixBuffObjs[0]); 
     } 
     else 
     { 
      pboSupported = 0; 
      pboMode = 0; // without PBO 
      printf("Video card does NOT support GL_ARB_pixel_buffer_object."); 
     } 

     glGetIntegerv(GL_MAX_TEXTURE_SIZE,&maxSz); 

     glClearColor(0.0f, 0.0f, 0.0f, 0.0f);  // This Will Clear The Background Color To Black 
     glClearDepth(1.0);       // Enables Clearing Of The Depth Buffer 
     glDepthFunc(GL_LESS);      // The Type Of Depth Test To Do 
     glEnable(GL_DEPTH_TEST);     // Enables Depth Testing 
     glShadeModel(GL_SMOOTH);     // Enables Smooth Color Shading 


     glMatrixMode(GL_PROJECTION); 
     //glLoadIdentity(); 



     hDC= wglGetCurrentDC(); 
#if 1 
     { // TSS 
      HWND hCurrentWindow = GetActiveWindow(); 
      char szTitle[256]="sample"; 
      //SetWindowText(hCurrentWindow,); 
      // SetWindowLongA (hCurrentWindow , GWL_STYLE, (GetWindowLongA (hCurrentWindow , GWL_STYLE) & ~(WS_CAPTION))); 
      SetWindowLongA (hCurrentWindow, GWL_STYLE, (WS_VISIBLE)); 
     } 
#endif 
     glEnable(GL_TEXTURE_2D); 
     glGenTextures(1, &texture); 
     glBindTexture(GL_TEXTURE_2D, texture); 

} 

int GL_Disply() 
{ 
    FILE *fptr=fopen("C:\\myRGB.rgb","rb"); 
    fseek(fptr,pos,SEEK_SET); 
    fread(guibuffer,sizeof(unsigned char),sizeof(unsigned char)*416*240*3,fptr); 
    pos+=416*240*3; 
    texture1.sizeX =416; 
    texture1.sizeY =240; 
    texture1.data = guibuffer; 

    glDepthFunc(GL_ALWAYS); 
    glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA); 
    glEnable(GL_BLEND); 
    glDisable(GL_LIGHTING); 

    //glEnable(GL_TEXTURE_2D); 

    glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR); 
    glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR); 
    glTexEnvf(GL_TEXTURE_ENV,GL_TEXTURE_ENV_MODE,GL_MODULATE); 

    glBindBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB, myPBO); 
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, texture1.sizeX, texture1.sizeY, 0, GL_RGB, GL_UNSIGNED_BYTE, NULL); 


    glBegin(GL_QUADS); 

    //glNormal3f(0.0f, 0.0f, 0.0f); 
    glTexCoord2f(0.0f, 1.0f); glVertex3f(-1.0f, -1.0f, 0.0f); 
    glTexCoord2f(1.0f, 1.0f); glVertex3f(1.0f, -1.0f, 0.0f); 
    glTexCoord2f(1.0f, 0.0f); glVertex3f(1.0f, 1.0f, 0.0f); 
    glTexCoord2f(0.0f, 0.0f); glVertex3f(-1.0f, 1.0f, 0.0f); 

    glEnd(); 

    glDisable(GL_BLEND); 
    glEnable(GL_DEPTH_TEST); 

    // Swap front and back rendering buffers 
    glfwSwapBuffers(); 
    //glDeleteTextures(1, &texture); 
    fclose(fptr); 

} 
int main(int argc, char *argv[]) 
{ 
    initGL(); // GL initialization 

    /*GPU memory allocation using C*/ 
    glGenBuffersARB(1, &myPBO); 
    glBindBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB, myPBO); 
    glBufferDataARB(GL_PIXEL_UNPACK_BUFFER_ARB, 416*240*3, NULL, GL_STREAM_DRAW_ARB); 
    guibuffer=(unsigned char*)glMapBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB, GL_WRITE_ONLY_ARB); 

    for(index=0;index<200;index++) 
    { 
     printf("frame %d displayed\r",index); 
     GL_Disply(); 
    } 

    return 0; 
} 

, 그것은 즉, 어떤 거기 BadPtr 문제가 유효한 주소를 반환

다음은 내 코드입니다. 나는 nVidia 그래픽 카드의 3 가지 모델을 가지고있는 3 개의 시스템으로 ckecked했고 출력은 흰색 스크린과 동일합니다.

그러나 나는 다른 그래픽 카드가있는 시스템에서 코드를 시도했지만 코드는 작동합니다. 또한 OpenGL 버전에는 문제가 없습니다.

위의 코드가 작동하도록하는 몇 가지 변경 사항이나 제안 사항을 제안하십시오.

답변

1

코드가 잘못되어 오류가 발생해야합니다. 다른 GPU에서는 작동하지 않아야합니다. 일반적으로 버퍼 객체는 클라이언트 메모리에 매핑되는 동안 GL에서 사용할 수 없습니다. PBO를 매핑 해제하려면 텍스처 이미지 사양의 소스로 사용할 수 있습니다. glTexImage 호출 직후에 PBO를 직접 다시 매핑하면 안되기 때문에 퍼포머가 줄어 듭니다. 이상적으로는 PBO의 링 버퍼를 사용하여 GL이 비동기 적으로 작동하도록 할 수 있습니다.

현대 GL은 또한 GL_ARB_buffer_storage 확장을 통해 영구 매핑 기능을 제공합니다 (4.4 이후로 핵심). 그러나 이것은 단점을 가지고 있습니다. 수동으로 버퍼 업데이트를 GL과 동기화해야합니다.이 유스 케이스에서는 아무 것도 얻지 못합니다.

+0

위의 코드에서 매핑 해제해야하는 장소를 알려주십시오. – sam

+0

@sam : 가장 간단한 변형은'glTexImage' 호출 이전에 unmap을 수행하고 곧바로 재 매핑을하는 것입니다. 하지만 이미 말했듯이, 공연은 그것이 할 수있는만큼 신랄하지 못합니다. – derhass

관련 문제