gilimcce
Messages postés33Date d'inscriptionjeudi 2 septembre 2004StatutMembreDernière intervention27 septembre 2004
-
13 sept. 2004 à 08:15
cs_djl
Messages postés3011Date d'inscriptionjeudi 26 septembre 2002StatutMembreDernière intervention27 novembre 2004
-
16 sept. 2004 à 22:57
Bonsoir,
J'alloue la mémoire d'un tableau contenant les pixels d'une image. Si je déclare classiquement mon tableau ( ex: image[512][1024][3] ) tout se passe bien, et j'arrive à mapper mon objet...
mais avec le code suivant, ça se complique :
l'image résultante est complètement brouillée...
pourtant l'allocation se passe sans erreur (testé) et je désalloue
(avec free, ou delete selon le cas c ou c++).
Est-ce un probleme d'initialisation de mon tableau ?
Texture est une variable globale, et l'allocation dynamique est faite dans une fonction secondaire.
Merci pour toute info,
Bonne soirée, et douce nuit.
cs_djl
Messages postés3011Date d'inscriptionjeudi 26 septembre 2002StatutMembreDernière intervention27 novembre 20047 14 sept. 2004 à 14:24
gluBuild2DMipmaps attend pas un tableau de 3 dimension mais un pointeur sur un buffer contenant les donnée (sinon ausun interet fonctionnel et impossible de passer en parametre un tableau a n dimension si les n-1 dernieres dimension ne sont pas fixées), si ca marche avec un tableau 3 dimension c'est parce que les elements sont bien entendu contigue
"Peut-il ne pas y avoir contiguité quand même ?"
oui, reli un cours sur pointeur et tableau c'est important si tu veux pas te planter par la suite
tu vera comment sont ordonnée les element dans un tableau multidimensionnel (qui est en fait un tableau de tableau...) mais ca reste un zone contigue, la seul difference avec un tableau unidimensionnel c'est que tu peux indexer les elements sur plusieurs dimensions
pour l'allocation dynamique, tu as fais une erreur malheureusement classique en croyant pouvoir allouer un tableau 3d a partir d'un pointeur de pointeur de pointeur (***texture)
par exemple si tu voulais allouer dynamiquement un tableau 2d de 20*50 par exemple, tu aurais fais
int **tab;
tab = new int*[20];for( unsigned i 0; i < 20; i ++ ) tab[i] new int[50];
seulement la les elements ne sont pas contigus car tu as d'abord allouer un tableau de 20 pointeur (int*), puis tu alloue pour chacun de ces pinteur une zone de 50 int qui est certe contigu, mais les zones ne le sont pas entre elle
d'ailleur pour acceder a un elements tu dois faire un double deferencement ce qui traduis bien le fais que les données sont eparpillée en memoire par segment de 50 elements
par exemple pour acceder a l'element , (5,6) tu ferais
tab[5][6] = 5;
mais c'est dans ce cas equivalent a *(*(tab + 5) + 6) 5;> double deferencement
comme je l'ai dis, la bonne facon d'allouer un tableau a n dimension si tu connais les n-1 derniere dimensions c'est
int (*tab)[50];
tab = new int[20][50];
et la aucun probleme
si tu ne connais pas toutes les dimensions, alors alloue un tableau unidimensionel et arrange toi pour l'indexer sur plusieurs dimensions (cf l'exemple de mon post precedent)
gilimcce
Messages postés33Date d'inscriptionjeudi 2 septembre 2004StatutMembreDernière intervention27 septembre 2004 14 sept. 2004 à 11:49
Le souci est qu'une de mes fonctions sous OpenGL recquiert un tableau 3D en paramètre :
gluBuild2DMipmaps(...,texture)
Si j'imprime le contenu de texture alloué dans le dur [720][1440][3] et alloué dynamiquement comme ds le 1er post, j'obtiens exactement les mêmes valeurs aux mêmes cases. Peut-il ne pas y avoir contiguité quand même ?
En l'occurence, j'utilise gluBuil2DMipmaps au lieu de glTexImage2D car mon jpeg n'a pas de dimensions en puissance de 2. gluBuild2DMipmaps se charge de redimmensionner.
gilimcce
Messages postés33Date d'inscriptionjeudi 2 septembre 2004StatutMembreDernière intervention27 septembre 2004 14 sept. 2004 à 16:27
Bon, si je te dis que ça marche...
Etonné ?
Dernière mise au point :
Lors de la déclaration et de la définition de ma fonction
"loadJpegImage" où texture est rempli puis
retourné au programme principal, j'ai une rreur à la compilation :
je déclare ma fonction en en-tete de cette façon :
unsigned char *[3] loadJpegImage(char *fichier);
et la défini ainsi :
unsigned char (*t)[3] loadJpegImage(char *fichier)
{
......
.......
}
J'imagine que c'est mal écrit....
Concernant la non contiguité, mon prof m'avait prévenu
qu'il y aurait un problème de ce genre avec mon allocation...
Merci de ne pas en etre resté là dans tes observations !
cs_djl
Messages postés3011Date d'inscriptionjeudi 26 septembre 2002StatutMembreDernière intervention27 novembre 20047 14 sept. 2004 à 17:03
en principe on retourne un pointeur sur le pemier element (multidimensionnel ou pas ca reste transparent)
unsigned char *loadJpegImage(...)
{
...
return (unsigned char *)texture;
}
theoriquement il y a une synthaxe pour ca, mais ce n'est pas necessiare
peut etre
(unsigned char *)[3] loadJpegImage(......) ?
sinon vasi a coup de typedef :)
typedef unsigned char *pPix [3];
pPix loadJpegImage(......);
mais globalement je pense pas que le prototype de ta fonction soit le design adequate, en principe quand on charge une texture (qqsoit le format de l'image) on recupere un pointeur sur les données, la largeur et la hauteur
moi je ferais
int loadJpegImage( char *buffer, size_t *width, size_t *height );
ou si tu prefere (mais ca reste strictement identique)
int loadJpegImage( unsigned char *buffer[3], size_t *width, size_t *height );
la valeur retour sert bien sur pour indiquer une eventuelle erreur
gilimcce
Messages postés33Date d'inscriptionjeudi 2 septembre 2004StatutMembreDernière intervention27 septembre 2004 15 sept. 2004 à 12:14
Bon...
Tout semblait etre bien parti...
Mais, le mappage ne se fait plus, a la place j'ai
"free(): invalid pointer 0x404abfd8!"
J'ai testé les adresses memoire des differents tableaux,
aucune ne correspond a celle generant l'erreur,
a moins qu'il ne s'agisse pas de l'adresse de l'element [0][0].
Bon, en attendant peut etre une lumineuse revelation du forum,
je vais afficher chaque adresse des elements de texture, l'erreur semble
venir de la.
Aussi, voilà le code, au cas zou...
Foutus pointeurs.
//////////////////// CHARGEMENT DE L'IMAGE//////////////////////////
int loadJpegImage(char *fichier, unsigned char (*texture)[3], int *Pt_width, int *Pt_height)
{
struct jpeg_decompress_struct cinfo;
struct jpeg_error_mgr jerr;
FILE *file;
unsigned char *ligne;
int i,j;
// rearrangement de l'image scannee dans le tableau de texture 3D
// ici nous sommes en niveau de gris, donc on copie le meme octet dans
// chacune des 3 cases RGB
// merci � jonatahn
for (i=0;i<t_height;i++)
for (j=0;j<t_width;j++)
{
texture[i*t_width+j][0]=image_gris[i*t_width+j];
texture[i*t_width+j][1]=image_gris[i*t_width+j];
texture[i*t_width+j][2]=image_gris[i*t_width+j];
}
// rearrangement de l'imtage scannee dans le tableau de texture 3D
for (i=0;i<t_height;i++)
for (j=0;j<t_width;j++)
{
texture[i*t_width*3+j*3][0]=image_rgb[i*t_width*3+j*3];
texture[i*t_width*3+j*3][1]=image_rgb[i*t_width*3+j*3+1];
texture[i*t_width*3+j*3][2]=image_rgb[i*t_width*3+j*3+2];
}
}
Les 3 dernieres lignes font appel a une routine detectant
les erreurs memoires, fuites.....
Cette fonction est appelée juste avant 'glutMainLoop()' :
vidage_malloc(text);
text est un pointeur sur unsigned char (ou sur (*)[3], on a essayé les 2 comme tu m'avais dit) et est passé en parametre dans la fonction loadJpegImage :
loadJpegImage(chemin, text, &width, &height);
chemin est l'adresse de l'image chargee.
dans le corps de cette fonction est declare dynamiquement un tableau d'unsigned char :
Donc text a bien une adresse pointant sur image_gris ?
En fait, autre souci, le mappage ne se fait plus, alors que la désallocation
ne devrait pas influer puisque venant bien apres l'affichage de la fenetre.
Je reste perplexe et... perdu.
Mais la vie est belle, si vs avez des questions, des suggestions, ou meme
qui sait, des reponses (djil ???), je suis pas tres loin.