2013-10-17 2 views
1

J'essaye de rendre les trames RVB en utilisant openGL. Lorsque la mémoire est allouée sur la CPU, le code fonctionne correctement. Cependant, lorsque j'alloue de la mémoire sur le GPU en utilisant le concept des Pixel Buffer Objects, j'obtiens un problème lors du rendu des images.OpenGL PBO ne fonctionne pas sur la carte graphique nVidia

Le problème est que la fenêtre d'affichage est complètement blanche. Lorsque le même code est exécuté sur d'autres cartes graphiques, le code fonctionne correctement. Cependant, quand je l'exécute sur un système ayant la carte graphique nVidia, le problème de ce problème d'écran blanc.

Ci-dessous mon code:

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

Je déboguée et vérifié si glMapBufferARB est de retour une adresse, il retourne une adresse valide à savoir pas là BadPtr problème. J'ai coché avec 3 systèmes ayant 3 modèles différents de carte graphique nVidia, la sortie est la même, c'est l'écran blanc.

Cependant, j'ai également essayé le code sur le système ayant d'autres cartes graphiques, le code fonctionne. De plus, il n'y a pas de problème dans la version OpenGL.

Suggérer quelques modifications ou quelque chose qui peut faire fonctionner le code ci-dessus.

Répondre

1

Votre code est invalide et devrait générer une erreur. Il ne devrait pas fonctionner sur différents GPU. Traditionnellement, les objets tampon ne peuvent pas être utilisés par le GL pendant qu'ils sont mappés à la mémoire du client. Vous devez démapper le PBO avant de pouvoir l'utiliser comme source pour votre spécification d'image de texture. Notez que vous ne devez pas remapper directement le PBO juste après l'appel glTexImage, car cela réduit la perforamce. Idéalement, vous utiliseriez un anneau tampon de PBO pour permettre au GL de fonctionner de manière asynchrone.

Modern GL offre également la fonctionnalité de mappages persistants via l'extension GL_ARB_buffer_storage (en core depuis la version 4.4, donc c'est vraiment nouveau). Mais ceci a l'inconvénient de devoir synchroniser manuellement les mises à jour de votre buffer avec le GL, sans vraiment gagner quoi que ce soit dans ce cas d'utilisation.

+0

pouvez-vous s'il vous plaît dites-moi à quel endroit je devrais faire démappage dans le code ci-dessus. – sam

+0

@sam: la variante la plus simple serait de faire l'unmap juste avant l'appel 'glTexImage', et de faire le remappage juste après. Mais comme je vous l'ai déjà dit, la performance ne sera pas aussi décevante qu'elle pourrait l'être. – derhass

Questions connexes