1
votes

I'm trying to render RGB frames using openGL. When memory is allocated on the CPU the code works fine. However, when i allocate memory on the GPU using the concept of Pixel Buffer Objects, i get a problem while rendering the frames.

The problem is that, the display window is completely white. When the same code is run on other graphics cards the code works fine. However when i run it on any system having nVidia graphics card, the face this white screen problem.

Below is my 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;
}

I have debugged and checked if glMapBufferARB is returning an address, it returns a valid address i.e. no BadPtr problem there. I have ckecked with 3 systems having 3 different models of nVidia graphics card, the output is same, that is the white screen.

However i also tried the code on system having other graphics cards, the code works. Further there is not problem in OpenGL version.

Suggest some changes or something that can make the above code work.

1

1 Answers

1
votes

Your code is invalid and should generate an error. It should not work on different GPUs. Traditionally, buffer objects can not be used by the GL while they are mapped to client memory. You have to unmap the PBO befor you can use it as source for your texture image specification. Note that you should not directly remap the PBO again just after the glTexImage call, since this is reducing perforamce. Ideally, you would use a ring buffer of PBOs to allow the GL to work asynchronously.

Modern GL also offers the feature of persistent mappings via the GL_ARB_buffer_storage extension (in core since 4.4, so it is really new). But this has the disadvantage the you have to manually synchronize your buffer updates with the GL, while not really gaining anything in this use case.