Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Access the whole video memory through OpenGL programming

How to access the video memory of graphics card through OpenGL programming, specifically, to get all contents of video memory?

I have tried the following two methods, but failed. With attaching them down, I hope you could point out the error in my program or in my understanding of the structure of video memory. Thanks in advance!

My basic idea is to continue allocating an uninitialized area in the video memory until exploring all the contents of video memory.

(1) In the main function, I create a window with double buffers (see following codes).

int main(int argc,char ** argv)
{
    glutInit(&argc, argv);
    glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGBA); // double buffers
    glutInitWindowPosition(0,0);
    glutInitWindowSize(windowWidth, windowHeight);
    glutCreateWindow("Hope to be successful!");
    glutDisplayFunc(myDisplay); // call back function "myDisplay"
    glutKeyboardFunc(keyboard);
    glutMainLoop();

    free(PixelData);
    return 0;
}

Then, in the "myDisplay" function, firstly I call glReadPixels() function to read out a given-size rectangle of pixels out of the back framebuffer, save these pixels information in an array "PixelData", and finally display those pixel information on the screen by calling glDrawPixels() function. After executing this program, only a black window appears. Black is the default color. So it means the window contains nothing. Then I have tried to read other areas out of the back framebuffer, and all of them contain nothing.

The conclusion from the above is that nothing is contained in the back framebuffer. However, this is unreasonable because the front buffer should only contain the current screen content/window, and thus other windows opened and minimized at the bottom of the screen should have their contents in the back framebuffer, but the back framebuffer is empty. So where are those windows (opened and minimized by me at the bottom) stored?

I guess the framebuffers (back and front) allocated for my program only occupy a small part of the whole video memory. Thus those minimized windows content should be stored in other places of video memory.

After some time, I read an introduction to OpenGL frameBuffer object (FBO), and there is a sentence: By default, OpenGL uses the framebuffer as a rendering destination that is created and managed entirely by the window system. This default framebuffer is called window-system-provided framebuffer. This seemingly verifies my above guess.

(2) Then I begin to work on FBO with the hope that FBO can help me to explore the whole video memory content.

In the below main function, I create a FBO and 7 renderbuffer objects (RBO), and then attach these 7 RBOs to this FBO through color attachment points.

const int RBO_COUNT = 7; //how many renderBuffer objects are created to attach to the frameBuffer object

int main(int argc, char **argv)
{
    ....
    glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_ALPHA); // display mode
    ...  

    // create a framebuffer object
    glGenFramebuffers(1, &fboId);
    glBindFramebuffer(GL_FRAMEBUFFER, fboId);

    //Create several 7 render buffer objects and attach all of them to the FBO.
    glGenRenderbuffers(RBO_COUNT, rbo);
    for (int i = 0; i < RBO_COUNT; i++)
    {
        glBindRenderbuffer(GL_RENDERBUFFER, rbo[i]);
        glRenderbufferStorage(GL_RENDERBUFFER, PIXEL_FORMAT, SCREEN_WIDTH, SCREEN_HEIGHT);
        glFramebufferRenderbuffer(GL_FRAMEBUFFER, colorAttach[i], GL_RENDERBUFFER, rbo[i]);
    }

   // check FBO status
   bool status = checkFramebufferStatus();
   if(!status) fboUsed = false;

    glBindFramebuffer(GL_FRAMEBUFFER, 0);
    ...

    glutMainLoop(); /* Start GLUT event-processing loop */
    return 0;
}

The below is the main part of my display callback function. Its function is to use the space key to control which renderBuffer object to read from, and then display its content on the screen.

void displayCB()
{
glBindFramebuffer(GL_FRAMEBUFFER, fboId);

//read this FBO attached RBO, save its content to fboContent
//"count" is a global variable, and is incremented by 1 (mod )every time pressing the space key of the keyboard.
glReadBuffer(colorAttach[count]); 
glReadPixels(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT, PIXEL_FORMAT, GL_UNSIGNED_BYTE, fboContent);

// back to normal window-system-provided framebuffer
glBindFramebuffer(GL_FRAMEBUFFER, 0); // unbind

// render to the default framebuffer //////////////////////////
glClear(GL_COLOR_BUFFER_BIT); // clear buffer
glClearColor(1, 0, 0, 1);
glDrawBuffer(GL_BACK);
glRasterPos2i(-1, -1);  
glDrawPixels(SCREEN_WIDTH, SCREEN_HEIGHT, PIXEL_FORMAT, GL_UNSIGNED_BYTE, fboContent);
glutSwapBuffers();
}

The final result is disappointing. The contents of all the renderBuffer objects are empty. I don't know the cause of this, because I thought that all these RBOs were never initialized and should contain some remaining contents.

like image 695
loong Avatar asked May 11 '12 17:05

loong


2 Answers

How to access the video memory of graphics card through OpenGL programming, specifically, to get all contents of video memory?

You cannot do that. Raw video memory cannot be accessed via OpenGL or DirectX. OpenGL only has various "buffers". The only thing that can access it is video driver, which is proprietary on windows platform. Free video memory is managed by video driver, and certain objects in video memory might exist only temporarily - driver can store copies in system memory, move them around and in offload them to disk when necessary. So your idea of managing free memory manually has no practical application.

You should be able to access video memory directly on OLD hardware - thing EGA/CGA/VGA, also on cards that support VESA, however you'll have no hardware acceleration, and you'll need to run something similar to MS-DOS or have kernel/driver access privilegies. You might be able to access memory contents on Linux, but i think it won't be helpful.

I'd recommend to forget about this idea.

Do you mean OpenGL cannot do such task? Actually, I have worked on this problem for nearly two months.

Something like that normally happens when you start a grandiose project without doing sufficient amount of research first. I'd recommend to learn from this experience. Before you start coding, always remember to check if you app hasn't been already written, has any practical application, can be created, there's a need for that app, and that you possess sufficient resources to create it.

Currently managing objects stored in video memory is driver's job.

If you want to see objects created by other applications, it'll be probably easier to hijack OpenGL api using proxy dlls, dll-injection or similar techniques and intercept relevant calls.

like image 59
SigTerm Avatar answered Nov 16 '22 08:11

SigTerm


How to access the video memory of graphics card through OpenGL programming, specifically, to get all contents of video memory?

Talk to the operating system, not OpenGL.

like image 2
genpfault Avatar answered Nov 16 '22 10:11

genpfault