Obtenir un fichier Jpeg en sortie, à la place de la fenetre glut

[Résolu]
Signaler
Messages postés
33
Date d'inscription
jeudi 2 septembre 2004
Statut
Membre
Dernière intervention
27 septembre 2004
-
Messages postés
1267
Date d'inscription
mercredi 1 janvier 2003
Statut
Membre
Dernière intervention
28 février 2007
-
Salut à tous :

J'ai quelques soucis conceptuels quant à l'enregistrement d'images. Cad : je modélise un objet 3D, et je dois avoir la possibilité soit d'afficher soit d'enregistrer un jpeg correspondant à ce qui aurait été affiché dans ma fenetre glut.

je dispose bien d'une fonction telle que :

/////////////////////////////////////////////////////

int
write_jpeg(FILE *outfile, int width, int height, unsigned char *rgb,
int quality)
{
struct jpeg_compress_struct cinfo;
struct jpeg_error_mgr jerr;

JSAMPROW scanline[1];

cinfo.err = jpeg_std_error(&jerr);
jpeg_create_compress(&cinfo);
jpeg_stdio_dest(&cinfo, outfile);

cinfo.image_width = width;
cinfo.image_height = height;
cinfo.input_components = 3;
cinfo.in_color_space = JCS_RGB;

jpeg_set_defaults(&cinfo);

jpeg_set_quality(&cinfo, quality, TRUE);

jpeg_start_compress(&cinfo, TRUE);

while (cinfo.next_scanline < (unsigned int) height)
{
scanline[0] = rgb + 3 * width * cinfo.next_scanline;
jpeg_write_scanlines(&cinfo, scanline, 1);
}

jpeg_finish_compress(&cinfo);
jpeg_destroy_compress(&cinfo);

return(1);
}

/////////////////////////////////////////////////////

Mais comment rempli-t-on le tableau d'unsigned char rgb ?
Comment avoir axès aux pixels affichés en fait ?

C'est sans doute facile, mais... bon ... c'est tout moi ça.

///////////////////////////////////////////////////

J'avais tjrs une question sans réponse sur le forum,
sur les moyens d'afficher du texte de couleur (autre que noir)
dans ma fenetre glut. L'utilisation de glutBitmapCharacter semble
limiter au noir, non ?

///////////////////////////////////////////////////

Excellent week end à tous,

10 réponses

Messages postés
101
Date d'inscription
samedi 9 février 2002
Statut
Membre
Dernière intervention
5 mai 2009

Salut

> Comment avoir axès aux pixels affichés en fait ?

// Premiere chose : dans quel buffer on doit lire ? (back ou front ?)

glReadBuffer(GL_FRONT); ou glReadBuffer(GL_BACK);

// Ensuite quelques declarations

int width = largeur de la fenetre
int height = hauteur de la fenetre
unsigned char *rgb = new unsigned char [3*width*height];

// On lit les pixels affichés

glReadPixels(0, 0, width, height, GL_RGB, GL_UNSIGNED_BYTE, rgb);
if(glGetError() != GL_NO_ERROR){
// probleme lors de la lecture
}

// Tu enregistre ton image

write_jpeg(outfile, width, height, rgb, quality);

// on libere la memoire allouée pour les pixels

delete [] rgb;

// L'utilisation de glutBitmapCharacter semble limiter au noir, non ?

Ah bon ?

tib
Messages postés
1267
Date d'inscription
mercredi 1 janvier 2003
Statut
Membre
Dernière intervention
28 février 2007
3
Ben voilà pour l'enregistrement tibur a répondu ^^
Pour ce qui concerne glutBitmapCharacter, peut-être en faisant un glColor3f() avant ça changera la couleur du texte?
Mais de toutes façons cette façon d'afficher du texte n'est pas géniale parce que d'une part il me semble bien que tu n'as pas la même flexibilité qu'avec un rendu par textures (genre pour faire tourner le texte, ou l'afficher en 3D, ou encore changer sa taille de façon dynamique...).

J'ai fait une classe pour afficher du texte au format TGA, t'as un exemple ici : http://perso.wanadoo.fr/funto/BaseCode2.rar

Bonne prog ;)

---------------------------------------------------------
Patience et longueur de temps font plus que force ni que rage....
Coucous flingueurs 3D : http://www.freewebs.com/cf3d/
Messages postés
33
Date d'inscription
jeudi 2 septembre 2004
Statut
Membre
Dernière intervention
27 septembre 2004

Merci bcp tibur....

J'ai tout de fois un souci
j'obtiens une image toute grise...
trouble, les données sont mal lues.
Et ce qq soit BACK ou FRONT pour le buffer.

pourtant

int
wri_jpeg(FILE *outfile, int width, int height, unsigned char *rgb,
int quality)
{
struct jpeg_compress_struct cinfo;
struct jpeg_error_mgr jerr;

JSAMPROW scanline[1];

cinfo.err = jpeg_std_error(&jerr);
jpeg_create_compress(&cinfo);
jpeg_stdio_dest(&cinfo, outfile);

cinfo.image_width = width;
cinfo.image_height = height;
cinfo.input_components = 3;
cinfo.in_color_space = JCS_RGB;

jpeg_set_defaults(&cinfo);

jpeg_set_quality(&cinfo, quality, TRUE);

jpeg_start_compress(&cinfo, TRUE);

while (cinfo.next_scanline < (unsigned int) height)
{
scanline[0] = rgb + 3 * width * cinfo.next_scanline;
jpeg_write_scanlines(&cinfo, scanline, 1);
}

jpeg_finish_compress(&cinfo);
jpeg_destroy_compress(&cinfo);

return(1);
}

void lect_buffer(int width, int height)
{
glReadBuffer(GL_BACK);
// ou glReadBuffer(GL_BACK);

unsigned char *rgb = new unsigned char [3*width*height];

// On lit les pixels affichés
glReadPixels(0, 0, width, height, GL_RGB, GL_UNSIGNED_BYTE, rgb);

// probleme lors de la lecture
if(glGetError() != GL_NO_ERROR){cout<<endl<<"Dans XPlanet [lecture buffer] : Probleme lecture buffer"<<endl;exit(0);}

// Choix du chemin
char phr2[100]; vidage(phr2,100);
strcat(phr2,"/stage/poirey/premierefois.jpg");

// wri_jpeg attend une chaine de type file
FILE *file2=fopen(phr2,"w");

// probleme lors de la l'ouverture
if (file2==NULL) {cout<<endl<<"Dans xplanet [lecture buffer] : Probleme ouverture jpeg"<<endl; exit(0);}

// appel de la fonction de creation du jpeg, une fois que les pixels ont ete lus et ranges
wri_jpeg(file2, width, height, rgb, 80);

// on libere la memoire allouée pour les pixels
delete [] rgb;
}

/////////////////////////////////////////////////

Pour gluBitmapCharacter... bah oui... semblerait.

A bientot....
Messages postés
33
Date d'inscription
jeudi 2 septembre 2004
Statut
Membre
Dernière intervention
27 septembre 2004

D'autant qu'il n'y a aucun message d'erreur
Et l'affichage glut est correct.
Messages postés
1267
Date d'inscription
mercredi 1 janvier 2003
Statut
Membre
Dernière intervention
28 février 2007
3
Hmm...je vois pas...
D'une part, t'as bien vérifié que wri_jpeg() fonctionne bien?
Après, sinon, y'a une source qui permet de faire une capture d'écran et d'enregistrer dans un TGA sur le site, c'est une des sources de xarier, si ça peut t'aider...

Si j'étais toi, d'abord je testerais wri_jpeg(), genre en lui donnant une mini-image du style
unsigned char data = {...les données RGB...};

Ensuite, si wri_jpeg fonctionne, vérifie que la partie glReadPixels() fonctionne, par exemple en utilisant les pixels lus pour les mettre sur une texture (glTexImage2D, ou plutôt gluBuild2DMipmaps ^^).

Enfin, si les 2 fonctionnent, ben je vois pas comment le lien entre les 2 ne marcherait pas...

---------------------------------------------------------
Patience et longueur de temps font plus que force ni que rage....
Coucous flingueurs 3D : http://www.freewebs.com/cf3d/
Messages postés
33
Date d'inscription
jeudi 2 septembre 2004
Statut
Membre
Dernière intervention
27 septembre 2004

Mouais,

la fonction wri_jpeg pose pas de probleme.
Mais readpixel, donc.

quand j'essais de mapper avec rgb rempli,
l'image est brouillée (comme qd je mappais mon onjet avec
un tableau dont les donnees n'étaient pas contigues)

faut croire que l'ordre dans lequel readpixel lit est différent
de celui ds lequel le fichier les attend.
Messages postés
33
Date d'inscription
jeudi 2 septembre 2004
Statut
Membre
Dernière intervention
27 septembre 2004

C'est bon... ça marche !!

Le probleme est que je lisais le buffer apres l'avoir vidé...
glutSwappBuffers.

Toujours pas d'idée pour afficher un texte en couleur
D'une manière simple ?

A plus... et merci.
Messages postés
33
Date d'inscription
jeudi 2 septembre 2004
Statut
Membre
Dernière intervention
27 septembre 2004

j'avais pas vu le post de Funtoo.
je vous tiens au courant
Messages postés
33
Date d'inscription
jeudi 2 septembre 2004
Statut
Membre
Dernière intervention
27 septembre 2004

Pour Founto >>

Merci pour ton lien :
si j'ai bien tout lu, il me faut :

utiliser les fichiers
TGALoader.h/cpp
TxtRenderer.h/cpp
Util.h/cpp

Si je divise ma fenetre en 3 :
sous glviewport j'appelle
TextRenderer::init
puis TextRenderer:Ecrire2D

Coté passage de parametre :
void TxtRenderer::Init(
const char* str_fichier_tga, // le fichier contenant la texture ?
Couleur couleur, // ... couleurs predefinies
int x, int y, // coordonnees ou la texture est inseree ?
TGAFiltering filtering, // ???
int largeur_car, int hauteur_car, // ok
int espace_v, int espace_h // espace entre mots et lignes ?
)

Merci pour les quelques precisions...

Ah... aussi,
pourquoi ecrit-on
#include "SDL.h" et pas <SDL.h> ?

et "SDL_opengl.h", d'où est chargé la bibl ?
Messages postés
1267
Date d'inscription
mercredi 1 janvier 2003
Statut
Membre
Dernière intervention
28 février 2007
3
"SDL.h" et "SDL_opengl.h", j'utilise ces notations parce que ce sont celles utilisées dans l'aide de SDL, mais tu peux mettre <SDL.h> si ça te chante.

Pour TxtRenderer :

void TxtRenderer::Init(

const char* str_fichier_tga, // le fichier contenant la texture, au format TGA (j'ai fait un prog pour créer une texture TGA si tu veux, c'est dans mes sources ;))

Couleur couleur, // couleur du texte, prédéfinie ou pas, tu peux utiliser le constructeur de la classe Couleur, qui prend 3 floats précisant les valeurs RGB.

int x, int y, // coordonnées du point où commence à s'écrire le texte

TGAFiltering filtering, // filtering de la texture; regarde dans TGALoader.h; le filtering, c'est une valeur que tu donnes à OpenGL qui empêche plus ou moins l'effet de pixellisation des textures.

int largeur_car, int hauteur_car, // ça t'as compris...

int espace_v, int espace_h //espace entre 2 lettres aux niveaux horizontal et vertical, tu peux modifier les valeurs du code que je t'ai filé si tu veux tester par toi-même.
)

Je devrais peut-être poster ce TxtRenderer sur CppFrance d'ailleurs...

---------------------------------------------------------
Patience et longueur de temps font plus que force ni que rage....
Coucous flingueurs 3D : http://www.freewebs.com/cf3d/