Hola Manué;
Para leer el buffer hay que usar la función glReadPixels, que nos
permite guardar el buffer de dibujado en un array. Debido a que el
convenio de OpenGL es guardar en memoria la última línea de píxeles
arriba (la imagen en "espejo" en vertical), hay que organizar un bucle
doble como el de la función que os adjunto, o bien en una línea tener
algo como esto:
for (i=0; i<ancho*alto*3; i++)
fprintf(f, "%u ",
b[(ancho*alto*3)-(ancho*3*((i/(ancho*3))+1))+(i%(ancho*3))]);
Creo que la versión de la función es más legible.
Si trabajas con varios buffers, recuerda que primero debes elegir el
buffer sobre el que leer los píxeles empleando glReadBuffer.
Adjunto ejemplillo completo de uso (con la tecla "s" se guarda una
captura del framebuffer). La función lista para copy+paste es
"snapshot"; guarda en PPM por ser un formato muy sencillo y cómodo. En
TGA es también cómodo y soporta canal alpha.
Saludos y happy coding!
Carlos.
-------------------------------------------------------------------
#include <GL/glut.h>
#include <GL/glu.h>
#include <GL/gl.h>
#include <stdio.h>
#include <stdlib.h>
int ancho=100, alto=100;
// Funcion para guardar el buffer actual como fichero PPM
void snapshot(char *nombrefichero)
{
FILE *f = fopen(nombrefichero, "w");
GLubyte *b;
int i, j;
fprintf (f, "P3\n");
fprintf (f, "%d %d\n", ancho, alto);
fprintf (f, "255\n");
b = (GLubyte*) malloc(ancho * alto * 3 * sizeof(GLubyte));
glReadPixels(0,0,ancho,alto,GL_RGB,GL_UNSIGNED_BYTE, b);
for (j=alto-1; j>=0; j--)
for (i=0; i<ancho; i++)
fprintf(f, "%u %u %u\n",
b[j*ancho*3+i*3],
b[j*ancho*3+i*3+1],
b[j*ancho*3+i*3+2]);
printf ("Imagen %s de %dx%d pixels guardada\n", nombrefichero, ancho,
alto);
free (b);
fclose(f);
}
void display()
{
glClear( GL_COLOR_BUFFER_BIT );
glLoadIdentity();
glTranslatef( 0.f, 0.f, -4.f );
glBegin( GL_TRIANGLES );
glColor3f( 1.f, 1.f, 1.f );
glVertex3f( -1.f, -1.f, 0.f );
glVertex3f( 1.f, -1.f, 0.f );
glVertex3f( 0.f, 1.f, 0.f );
glEnd();
glutSwapBuffers();
}
void resize(int w, int h)
{
// Viewport para dibujar en toda la ventana
glViewport( 0, 0, w, h );
// Actualizamos en la matriz de proyección el ratio ancho/alto
glMatrixMode( GL_PROJECTION );
glLoadIdentity();
gluPerspective( 50., (double)w/(double)h, 1., 10. );
// Volvemos al modo Vista de Modelo
glMatrixMode( GL_MODELVIEW );
}
void keyboard (unsigned char key, int x, int y)
{
switch (key) {
case 's' :
snapshot("prueba.ppm");
break;
}
glutPostRedisplay();
}
// Inicializacion del estado de OpenGL
// ------------------------------------
void init()
{
glEnable (GL_DEPTH_TEST);
}
int main( int argc, char** argv )
{
glutInit( &argc, argv );
glutInitDisplayMode( GLUT_RGB | GLUT_DOUBLE );
glutInitWindowSize( ancho, alto );
glutCreateWindow( "Hola Mundo" );
init();
// Registro de funciones de callback
glutDisplayFunc(display);
glutReshapeFunc(resize);
glutKeyboardFunc(keyboard);
glutMainLoop();
return 0;
}
> Ahora bien, me ha surgido una duda que la he intentando solucionar
> "googleando", pero no he tenido éxito.
>
> Se me habia ocurrido que no estaría mal que en el menú contextual que he
> creado, apareciese una opción del tipo "guardar como", que te permitiese
> guardar la imagen actual de la ventana en cualquier directorio.
>
> ¿Alguno de ustedes ha hecho algo parecido en OpenGL?
>
> Yo como siempre en cuanto lo sepa os lo cuento.
>
> Un saludo, gracias de todos modos.
>
> _________________________________________________________________
> Horóscopo, tarot, numerología... Escucha lo que te dicen los astros.
> http://astrocentro.msn.es/
>
> _______________________________________________
> CRySoL mailing list
> http://crysol.inf-cr.uclm.es/
> https://arco.inf-cr.uclm.es/cgi-bin/mailman/listinfo/crysol
>
>
_______________________________________________
CRySoL mailing list
http://crysol.inf-cr.uclm.es/
https://arco.inf-cr.uclm.es/cgi-bin/mailman/listinfo/crysol