2012-05-11 11 views
5

¿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.

+0

"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 *. –

+0

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

+0

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é. –

Respuesta

1

¿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?

Hable con el sistema operativo, no con OpenGL.

+0

¿Quiere decir que OpenGL no puede hacer esa tarea? En realidad, he trabajado en este problema durante casi dos meses. Si OpenGL no puede, tendré que reiniciar mi trabajo. Además, ¿podría decir algo más sobre "hablar con el sistema operativo"? – loong

-1

No está claro por qué que quiere hacer esto, y cuál es su juego final, pero me parece que está intentando acceder a la información gráfica que se produce por las aplicaciones 3 ª parte.

En caso de que esté tratando de lograr what FRAPS does, tenga en cuenta que utiliza una técnica completamente diferente de la que está tratando de hacer (una mucho más simple): interceptar llamadas a bibliotecas gráficas como OpenGL y DirectX.

+0

Estoy tratando de verificar si un tipo de ataque potencial es realmente factible. Y acceder a toda la memoria de video es parte del proceso de verificación. Gracias por la respuesta. – loong

+0

Tu enlace está roto. ¿Puedes intentar arreglarlo (es decir, puedes encontrar una URL actualizada?) Ya que estoy interesado en "cómo funciona FRAPS" ​​para [implementar algo similar] (http://stackoverflow.com/q/13781777/592323) ... – leemes

+0

2 minutos de búsqueda en Internet. :(Está arreglado. – karlphillip

6

¿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?

No puede hacer eso. La memoria de video sin formato no se puede acceder a través de OpenGL o DirectX. OpenGL solo tiene varios "búferes". Lo único que puede acceder es el controlador de video, que es propiedad de la plataforma de Windows. La memoria de video gratuita es administrada por un controlador de video, y ciertos objetos en la memoria de video pueden existir solo temporalmente: el controlador puede almacenar copias en la memoria del sistema, moverlas y descargarlas al disco cuando sea necesario. Entonces, su idea de administrar la memoria libre manualmente no tiene aplicación práctica.

Debería poder acceder a la memoria de video directamente en hardware OLD - cosa EGA/CGA/VGA, también en tarjetas compatibles con VESA, sin embargo no tendrá aceleración de hardware, y deberá ejecutar algo similar a MS-DOS o tiene privilegios de acceso al kernel/controlador. Es posible que pueda acceder a los contenidos de la memoria en Linux, pero creo que no será útil.

Recomendaría olvidarse de esta idea.

¿Quiere decir que OpenGL no puede hacer tal tarea? En realidad, he trabajado en este problema durante casi dos meses.

Algo así normalmente ocurre cuando se inicia un proyecto grandioso sin hacer una cantidad suficiente de investigación primero. Recomiendo aprender de esta experiencia. Antes de comenzar a codificar, recuerde siempre verificar si su aplicación aún no se ha escrito, si tiene alguna aplicación práctica, si se puede crear, si existe la necesidad de esa aplicación y si cuenta con los recursos suficientes para crearla.

Actualmente, la gestión de objetos almacenados en la memoria de video es tarea del conductor.

Si desea ver objetos creados por otras aplicaciones, probablemente sea más fácil secuestrar la API OpenGL utilizando proxy dlls, dll-injection o técnicas similares e interceptar llamadas relevantes.

+0

Gracias por su explicación detallada! Muy útil! Será algo terrible para mí si todo lo que dice resulta ser cierto. – loong

+0

no tiene que ser hardware antiguo; simplemente puede poner una aplicación de BIOS en un cd/disquete. Todas las PC lo admiten. – Dmitry

Cuestiones relacionadas