Votre question

OpenGL: save screenshot

Tags :
  • Programme
  • Programmation
Dernière réponse : dans Programmation
10 Février 2011 16:20:03

Bonjour,

Je programme en C++ et j'utilise OpenGL pour faire une animation. Je n'arrive pas cependant à sauvegarder les images créées par opengl. J'utilise glreadbuffer et glreadpixels mais l'image créée ne contient que la moitié du buffer.

Voici ma fonction display


  1. void display(void)
  2. {
  3.  
  4. glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
  5. glMatrixMode(GL_MODELVIEW);
  6. glClearColor(0.8f, 0.8f, 0.8f, 0.0f);
  7.  
  8.  
  9. glPushMatrix();
  10. glTranslatef(0.0, 0.0, -5.0);
  11. displayObject();
  12. glPopMatrix();
  13.  
  14. glPushAttrib(GL_ENABLE_BIT);
  15. glDisable(GL_DEPTH_TEST); glDisable(GL_LIGHTING);
  16. glMatrixMode(GL_PROJECTION);
  17.  
  18. glPushMatrix();
  19. glLoadIdentity();
  20. gluOrtho2D(0, 3000, 0, 3000);
  21. glMatrixMode(GL_MODELVIEW);
  22. glPushMatrix();
  23. glLoadIdentity();
  24. glPopMatrix();
  25. glMatrixMode(GL_PROJECTION);
  26. glPopMatrix();
  27.  
  28. glPopAttrib();
  29.  
  30. OGL_SaveScreenshot(counter++);
  31.  
  32. glutSwapBuffers();
  33. }


et la fonction pour sauvegarder le contenu du buffer:

  1. void OGL_SaveScreenshot(int i)
  2. {
  3.  
  4. char filename[2048];
  5.  
  6. std::ostringstream buff; buff<<"SavedImage"<<i<<".png";
  7. strcpy(filename, buff.str().c_str());
  8.  
  9. png_structp png_write = png_create_write_struct(PNG_LIBPNG_VER_STRING,NULL, OGL_png_error, OGL_png_warn);
  10.  
  11. if (!png_write)
  12. {
  13. printf("Error creating PNG write struct.\n");
  14. return;
  15. }
  16.  
  17. png_infop png_info = png_create_info_struct(png_write);
  18. if (!png_info)
  19. {
  20. png_destroy_write_struct(&png_write, (png_infopp)NULL);
  21. printf("Error creating PNG info struct.\n");
  22. return;
  23. }
  24.  
  25. if (setjmp(png_jmpbuf(png_write)))
  26. {
  27. png_destroy_write_struct(&png_write, &png_info);
  28. printf("Error calling setjmp()\n");
  29. return;
  30. }
  31.  
  32. // open the file to write
  33. FILE *savefile = fopen(filename, "wb");
  34. if (savefile == NULL)
  35. {
  36. printf("Error opening '%s' to save screenshot.\n", filename);
  37. return;
  38. }
  39.  
  40. png_init_io(png_write, savefile);
  41.  
  42. unsigned char *pixels = (unsigned char*)malloc( glWindowWidth * glWindowHeight*3 );
  43. glReadBuffer(GL_BACK);
  44. glReadPixels(0,0,glWindowWidth,glWindowHeight,GL_RGB,GL_UNSIGNED_BYTE,pixels);
  45.  
  46. if(NULL==pixels)
  47. printf("Error NO PIXELS \n");
  48.  
  49. // set the info
  50. png_set_IHDR(png_write, png_info, glWindowWidth, glWindowHeight, 8, PNG_COLOR_TYPE_RGB,
  51. PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_DEFAULT,PNG_FILTER_TYPE_DEFAULT);
  52. // lock the screen, get a pointer and row pitch
  53. long pitch = glWindowWidth * 3;
  54.  
  55. png_byte **row_pointers;
  56. row_pointers = (png_byte **) malloc(glWindowHeight * sizeof(png_bytep));
  57. for (int i = 0; i < glWindowHeight; i++)
  58. {
  59. row_pointers[i] = (png_byte *) (pixels + i * pitch);
  60. }
  61.  
  62. png_set_rows(png_write, png_info, row_pointers);
  63. png_write_png(png_write, png_info, 0, NULL);
  64.  
  65. // free memory
  66. free(row_pointers);
  67. png_destroy_write_struct(&png_write, &png_info);
  68. free(pixels);
  69. }


Est-ce que quelqu'un aurait une idée ?

Merci

Autres pages sur : opengl save screenshot

a b L Programmation
10 Février 2011 20:20:31

Dans glReadPixels, il faut donner le coin bas gauche du viewport (et pas de la fenêtre). C'est donc dans les coordonnées du viewport qu'il te faut indiquer le point d'origine.

Je n'ai pas testé, mais j'imagine que tu as le quart haut droit de l'écran, (0, 0) se trouvant au centre de l'écran.

m
0
l
22 Février 2011 15:44:05

CRicky a dit :
Dans glReadPixels, il faut donner le coin bas gauche du viewport (et pas de la fenêtre). C'est donc dans les coordonnées du viewport qu'il te faut indiquer le point d'origine.

Je n'ai pas testé, mais j'imagine que tu as le quart haut droit de l'écran, (0, 0) se trouvant au centre de l'écran.


J'ai sauvegardé l'image en utilisant openCV et ca marche. Je crois que le problème est lié aux paramètres des fonctions qui permettent d'ecrire l'image tel
# png_set_IHDR(png_write, png_info, glWindowWidth, glWindowHeight, 8, PNG_COLOR_TYPE_RGB,
# PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_DEFAULT,PNG_FILTER_TYPE_DEFAULT);
m
0
l
Tom's guide dans le monde
  • Allemagne
  • Italie
  • Irlande
  • Royaume Uni
  • Etats Unis
Suivre Tom's Guide
Inscrivez-vous à la Newsletter
  • ajouter à twitter
  • ajouter à facebook
  • ajouter un flux RSS