Se connecter avec
S'enregistrer | Connectez-vous

OpenGL: save screenshot

Dernière réponse : dans Programmation

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

Lassé par la pub ? Créez un compte
Expert Programmation

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.

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);
Lassé par la pub ? Créez un compte
Tom's guide dans le monde