Как получить доступ к видеопамяти видеокарты через программирование OpenGL, в частности, чтобы получить все содержимое видеопамяти?
Я пробовал следующие два метода, но потерпел неудачу. Прикрепив их, надеюсь, вы могли бы указать на ошибку в моей программе или в моем понимании устройства видеопамяти. Заранее спасибо!
Моя основная идея состоит в том, чтобы продолжать выделять неинициализированную область в видеопамяти до тех пор, пока не будет исследовано все содержимое видеопамяти.
(1) В основной функции я создаю окно с двойными буферами (см. следующие коды).
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;
}
Затем в функции «myDisplay» я сначала вызываю функцию glReadPixels() для считывания прямоугольника пикселей заданного размера из заднего буфера кадра, сохраняю информацию об этих пикселях в массиве «PixelData» и, наконец, отображаю эту информацию о пикселях на экран, вызвав функцию glDrawPixels(). После выполнения этой программы появляется только черное окно. Черный цвет по умолчанию. Это означает, что в окне ничего нет. Затем я попытался прочитать другие области из заднего фреймбуфера, и все они ничего не содержат.
Вывод из вышесказанного - в заднем фреймбуфере ничего не содержится. Однако это неразумно, потому что передний буфер должен содержать только текущее содержимое экрана/окно, и поэтому другие окна, открытые и свернутые в нижней части экрана, должны иметь свое содержимое в заднем фреймбуфере, но задний фреймбуфер пуст. Так где же хранятся эти окна (открытые и свернутые мной внизу)?
Я предполагаю, что фреймбуферы (задний и передний), выделенные для моей программы, занимают лишь небольшую часть всей видеопамяти. Таким образом, содержимое свернутого окна должно храниться в других местах видеопамяти.
Через некоторое время я прочитал введение в объект OpenGL frameBuffer (FBO), и там есть предложение: По умолчанию OpenGL использует фреймбуфер в качестве места назначения рендеринга, которое создается и полностью управляется оконной системой. Этот кадровый буфер по умолчанию называется кадровым буфером, предоставляемым оконной системой. Это, по-видимому, подтверждает мою догадку выше.
(2) Затем я начинаю работать над FBO в надежде, что FBO поможет мне исследовать все содержимое видеопамяти.
В приведенной ниже основной функции я создаю FBO и 7 объектов буфера рендеринга (RBO), а затем прикрепляю эти 7 RBO к этому FBO через точки привязки цвета.
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;
}
Ниже приведена основная часть моей функции обратного вызова дисплея. Его функция заключается в использовании клавиши пробела для управления тем, из какого объекта renderBuffer читать, а затем отображать его содержимое на экране.
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();
}
Окончательный результат разочаровывает. Содержимое всех объектов renderBuffer пусто. Я не знаю причину этого, потому что я думал, что все эти RBO никогда не были инициализированы и должны содержать некоторое оставшееся содержимое.