Bonjour, je débute en c et pour m'amuser, j'ai codé la fractal de Mandelbrot avec la SDL2 : pour afficher la fractal il faut faire beaucoup de calculs et ça peut prendre un peu de temps.
Pour la dessiner, il faut utiliser la suite Z(n+1) = Z² + c mais on peut aussi utiliser une formule plus général en mettant Z^d (ou d peut varier) au lieu de Z². (on utilise la suite Z(n+1) = Z^d +c)
Je me suis amusé à faire un programme qui affiche donc la fractale plusieurs fois, en faisant varier l'exposant de la formule entre 2 et 10 avec un pas de 0.1, en exportant une image du résultat à chaque incrémentation de d. Mon problème, (j'y viens enfin) est qu'au lieu de voir sur l'écran la fractale qui change de forme au fur et à mesure, il y a écrit que ma fenêtre "ne répond pas" alors que pourtant, je vois que le programme exporte bien les images...
Du coup j'aimerais savoir pourquoi mon programme ne répond pas et affiche une image figée, alors qu'il continue de fonctionner?
Bon jsp si j'ai été clair mais j'espère que vous comprendrez !
donc voici le code qui permet de mettre chaque pixel de la bonne couleur :
et voici le code qui actualise la fenêtre :
je vous ai épargné les initialisations qui ne changent pas grand chose...
Ensuite, qu'est ce que ça veut dire " il faut que tu dépiles les events" et qu'est ce que le double buffering?? (je débute donc je connais pas encore tout ça )
Et au passage je rectifie un truc : la fenêtre ne répond pas dès que je clique qq part ou que je fais une action avec l'ordi , si je ne touche à rien, je vois la fenêtre qui s'actualise comme je veux...
Ah dsl je savais pas du coup voici ma réponse sans capture d'écran :
Voilà mon code :
//Les librairies
#include <SDL.h>
#include <stdio.h>
#include <stdlib.h>
#include <complex.h>
#include<SDL_image.h>
//Les constantes
#define LARGEUR 1200
#define HAUTEUR 1200
#define XMIN -2
#define XMAX 5
#define YMIN -1.25
#define YMAX 1.25
#define ITERATIONS 50
//Les prototypes
int initialisations(SDL_Window ** fenetre, SDL_Renderer **rendu, SDL_Surface **surface);
int dessiner_le_fractal(SDL_Surface *surface, double exposant, double xmin, double xmax, double ymin, double ymax);
int main(int argc, char * argv[])
{
//Variables utiles :
SDL_Window * fenetre = NULL;
SDL_Renderer* rendu = NULL;
SDL_Surface* surface = NULL;
SDL_Texture* texture = NULL;
//initialisation de tout
initialisations(&fenetre, &rendu, &surface);
double exposant = 2, xmin = -2, xmax = 0.5, ymin = -1.25, ymax = 1.25;
char nom_du_fichier[100] = {0};
int nombre = 1;
int activation =1;
double zoomx = -1.401155;
double zoomy = 0;
double vzoom = 1.05;
for(exposant = 2; exposant <10; exposant += 0.1)
{
dessiner_le_fractal(surface, exposant, xmin, xmax, ymin, ymax);
texture = SDL_CreateTextureFromSurface(rendu, surface);
SDL_RenderCopy(rendu, texture, NULL, NULL);
SDL_RenderPresent(rendu);
/* sprintf(nom_du_fichier, "mandelbrot/mandelbrot_%d.jpg", nombre);
IMG_SaveJPG(surface, nom_du_fichier, 100);
ymin = ((ymin - zoomy) / vzoom) + zoomy;
ymax = ((ymax - zoomy)/vzoom) + zoomy;
xmin = ((xmin - zoomx) / vzoom) + zoomx;
xmax = ((xmax - zoomx)/vzoom) + zoomx; ==> on s'en fiche de ça aussi, c'est juste pour zoomer*/
SDL_Delay(100);
}
SDL_Delay(15000);
IMG_Quit();
SDL_FreeSurface(surface);
SDL_DestroyWindow(fenetre);
SDL_DestroyRenderer(rendu);
SDL_Quit();
}
int initialisations(SDL_Window ** fenetre, SDL_Renderer **rendu, SDL_Surface **surface)
{
//initialise la SDL
if(SDL_Init(SDL_INIT_VIDEO) != 0)
{
fprintf(stderr, "Erreur d'initialisation de la SDL : %s", SDL_GetError());
SDL_Quit();
return -1;
}
IMG_Init(IMG_INIT_JPG);
//créer une fenetre
*fenetre = SDL_CreateWindow("Le fractale de toto", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED,
LARGEUR, HAUTEUR, SDL_WINDOW_SHOWN);
if(*fenetre == NULL)
{
fprintf(stderr, "Erreur de création de la fenetre : %s", SDL_GetError());
SDL_DestroyWindow(*fenetre);
SDL_Quit();
return -1;
}
//creer un rendu
*rendu = SDL_CreateRenderer(*fenetre, -1, SDL_RENDERER_ACCELERATED);
if(*rendu == NULL)
{
fprintf(stderr, "Le rendu est kapout : %s", SDL_GetError());
SDL_DestroyRenderer(*rendu);
SDL_DestroyWindow(*fenetre);
SDL_Quit();
return -1;
}
//création de la surface!
*surface = SDL_CreateRGBSurfaceWithFormat(0, LARGEUR, HAUTEUR, 32, SDL_PIXELFORMAT_RGBA8888);
if(*surface == NULL)
{
fprintf("Erreur de création de la surface : %s", SDL_GetError());
SDL_FreeSurface(surface);
SDL_DestroyRenderer(*rendu);
SDL_DestroyWindow(*fenetre);
SDL_Quit();
return -1;
}
return 0;
}
int dessiner_le_fractal(SDL_Surface *surface, double exposant, double xmin, double xmax, double ymin, double ymax)
{
double x=0, y=0;
Uint32 *pixels = surface->pixels;
Uint32 couleur = SDL_MapRGB(surface->format, 0, 255, 0);
SDL_LockSurface(surface);
size_t i, j;
for(i = 0; i < HAUTEUR; i++)
{
for(j = 0; j < LARGEUR; j++)
{
x = (j*((xmax-xmin)/(double)LARGEUR)+xmin);
y = (i*((ymax-ymin)/(double)HAUTEUR)+ymin);
double complex c = x + y*I;
double complex vieuxz = 0.0 + 0.0*I;
double complex z= 0+0*I;
int cpt = 0;
while((creal(z) *creal(z)) + (cimag(z) *cimag(z)) < 4 && cpt <ITERATIONS)
{
vieuxz = z;
// z = (vieuxz * vieuxz) + c;
//c = c*c -0.8 +0.156*I; ==> il ne faut pas regarder ces lignes, c'est juste quand je veux changer la forme de la fractal
z = cpow(vieuxz, exposant) + c;
cpt ++;
}
if(cpt >= ITERATIONS)
{
pixels[i * LARGEUR + j] = SDL_MapRGBA(surface->format, 0, 0, 0, 255);
}else{
pixels[i * LARGEUR + j] = SDL_MapRGBA(surface->format, (Uint8)(1*cpt), (Uint8)(5*cpt), (Uint8)(10*cpt), 255);
}
}
surface->pixels = pixels;
SDL_UnlockSurface(surface);
}
}
Qqu'est ce que ça veut dire " il faut que tu dépiles les events" et qu'est ce que le double buffering?? (je débute donc je connais pas encore tout ça o_O)
Et au passage je rectifie un truc : la fenêtre ne répond pas dès que je clique qq part ou que je fais une action avec l'ordi , si je ne touche à rien, je vois la fenêtre qui s'actualise comme je veux...
Tout d'abord, comme tu génères une texture a chaque tour de boucle, ligne 41, il faut la détruire à la fin : par exemple après ton SDL_delay ligne 50 :
SDL_DestroyTexture(texture);
Ensuite ton dernier soucis, c'est du dépilage d'event :
Essaie par exemple ligne 49 tu mets :
SDL_Event event;
while(SDL_PollEvent(&event))
{
}
Pour faire simple :
Chaque fois que tu bouges la souris, que tu appuies sur une touche, que tu cliques, ou n'importe quel événement extérieur, un "bonhomme qui porte la pancarte de ce qui s'est passé" se met dans une file d'attente.
Si tu laisses pourrir la file d'attente, au bout d'un moment elle va saturer.
Donc il faut... "faire passer les gens", fait défiler.
Pour l'instant je vois que tu n'as pas envie de savoir sur quelle touches on a appuyé etc, donc laisse les passer sans les regarder : d'ou le while vide dont je te parle : tant qu'il y a des events, laisse passer.... dépile (de empiler/dépiler)
× Après avoir cliqué sur "Répondre" vous serez invité à vous connecter pour que votre message soit publié.
× Attention, ce sujet est très ancien. Le déterrer n'est pas forcément approprié. Nous te conseillons de créer un nouveau sujet pour poser ta question.
jaj de jej
Recueil de code C et C++ http://fvirtman.free.fr/recueil/index.html
On écrit "j'ai tort", pas "tord" qui est le verbe "tordre" à la 3ème personne de l'indicatif présent
jaj de jej
On écrit "j'ai tort", pas "tord" qui est le verbe "tordre" à la 3ème personne de l'indicatif présent
jaj de jej
Recueil de code C et C++ http://fvirtman.free.fr/recueil/index.html