2013-10-17 65 views
1

我想使用openGL渲染RGB帧。当在CPU上分配内存时,代码工作正常。但是,当我使用像素缓冲区对象的概念在GPU上分配内存时,渲染帧时出现问题。OpenGL PBO的不工作nVidia图形卡

问题是,显示窗口是完全白色的。当其他图形卡上运行相同的代码时,代码工作正常。但是,当我在任何有nVidia图形卡的系统上运行它时,面对这个白色屏幕问题。

下面是我的代码:

#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; 
} 

我已经调试和检查,如果glMapBufferARB被返回的地址,它会返回一个有效的地址,即没有BadPtr问题存在。我有3个系统有3个不同型号的nVidia图形卡,输出是相同的,这是白色的屏幕。

但是我也试过系统上有其他图形卡的代码,代码工作。此外在OpenGL版本中没有问题。

建议一些更改或可以使上述代码正常工作的内容。

回答

1

你的代码无效,应该会产生错误。它不应该在不同的GPU上工作。传统上,GL在映射到客户端内存时不能使用缓冲区对象。您必须取消对PBO的映射,您可以将其用作纹理图像规范的源代码。请注意,您不应在拨打glTexImage后再次直接重新映射PBO,因为这会降低通话效率。理想情况下,您可以使用PBO的环形缓冲区来允许GL异步工作。现代GL还通过GL_ARB_buffer_storage扩展提供了持久映射功能(从4.4开始,在核心中,所以它真的是新的)。但是这样做的缺点是你必须手动同步你的缓冲区更新和GL,而在这个用例中并没有真正获得任何东西。

+0

你能告诉我在哪个地方我应该在上面的代码中取消映射。 – sam

+0

@sam:最简单的变体是在'glTexImage'调用之前进行unmap,然后重新映射。但正如我已经告诉过你的那样,表演不会像以前那样神往。 – derhass