¿Cómo acceder a la memoria de video de la tarjeta gráfica a través de la programación OpenGL, específicamente, para obtener todo el contenido de la memoria de video?Acceda a toda la memoria de video a través de la programación OpenGL
He intentado los dos métodos siguientes, pero he fallado. Al adjuntarlos, espero que puedan señalar el error en mi programa o en mi comprensión de la estructura de la memoria de video. ¡Gracias por adelantado!
Mi idea básica es continuar asignando un área no inicializada en la memoria de video hasta explorar todo el contenido de la memoria de video.
(1) En la función principal, creo una ventana con búferes dobles (consulte los códigos siguientes).
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;
}
Luego, en la función "myDisplay", en primer lugar me llaman glReadPixels() para leer un rectángulo de tamaño dado de píxeles fuera de la framebuffer espalda, salvar estos píxeles información en una matriz "PixelData", y finalmente mostrar esa información de píxeles en la pantalla llamando a la función glDrawPixels(). Después de ejecutar este programa, solo aparece una ventana negra. El negro es el color predeterminado. Entonces, significa que la ventana no contiene nada. Luego intenté leer otras áreas fuera del framebuffer posterior, y todas ellas no contienen nada.
La conclusión de lo anterior es que nada está contenido en el back framebuffer. Sin embargo, esto no es razonable porque el buffer frontal solo debe contener el contenido/ventana de la pantalla actual, y por lo tanto, otras ventanas abiertas y minimizadas en la parte inferior de la pantalla deben tener su contenido en el framebuffer, pero el framebuffer está vacío. Entonces, ¿dónde se almacenan esas ventanas (abiertas y minimizadas por mí en la parte inferior)?
Supongo que los framebuffers (atrás y frente) asignados para mi programa solo ocupan una pequeña parte de toda la memoria de video. Por lo tanto, el contenido minimizado de Windows debe almacenarse en otros lugares de la memoria de video.
Después de un tiempo, leo una introducción al objeto frameBuffer (FBO) de OpenGL, y hay una oración: de forma predeterminada, OpenGL usa el framebuffer como un destino de representación que se crea y administra completamente por el sistema de ventanas. Este framebuffer predeterminado se llama framebuffer provisto por el sistema de ventanas. Esto aparentemente verifica mi suposición anterior.
(2) Luego empiezo a trabajar en FBO con la esperanza de que FBO pueda ayudarme a explorar todo el contenido de la memoria de video.
En la siguiente función principal, creo un FBO y 7 objetos renderbuffer (RBO), y luego conecto estos 7 RBO a este FBO a través de los puntos de fijación de color.
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;
}
La siguiente es la parte principal de la función de devolución de llamada de mi pantalla. Su función es usar la tecla espacio para controlar de qué objeto renderBuffer leer, y luego mostrar su contenido en la pantalla.
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();
}
El resultado final es decepcionante. El contenido de todos los objetos renderBuffer está vacío. No sé la causa de esto, porque pensé que todas estas RBO nunca se inicializaron y deberían contener algunos contenidos restantes.
"Pensé que todas estas RBO nunca se inicializaron y deberían contener algunos contenidos restantes". Entonces deberías volver a leer la especificación. Dice que sus contenidos están * indefinidos *. Indefinido podría significar "contenido restante". También podría significar "memoria cero". Podría significar "memoria configurada en un color arbitrario para que sea más fácil detectar errores". No definido significa * indefinido *. –
La especificación (http://www.opengl.org/wiki/Renderbuffer_Object) dice que "el renderbuffer se crea sin inicializar". Creo que tienes razón. Si los RBO no inicializados están vacíos o contienen algunos contenidos restantes está determinado por cuándo se crean esos RBO. Si toda la memoria de video se ha utilizado una vez y algunos de ellos no están asignados, los RBO recién creados probablemente contengan algunos contenidos anteriores. – loong
Esa no es la especificación; eso es un articulo Wiki La especificación se encuentra en el [Registro de OpenGL] (http://www.opengl.org/registry/).Pero gracias por señalar el error; Lo arreglaré. –