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.