Horloge graphique en sdl

Soyez le premier à donner votre avis sur cette source.

Vue 10 458 fois - Téléchargée 522 fois

Description

C'est une simple horloge graphique en sdl... Je pense que c'est un bon début pour commencer en sdl, plusieurs fonctions basiques interviennent comme la gestion du temps, l'affichage de pixels, tracer une droite... La plus part de ces fonctions sont très facilement portable sur d'autre projets.

Compilé sous Visual, aucune erreur, aucun warning.

Nécessite bien entendu d'avoir installé la librairie SDL!!!

Source / Exemple :


// Horloge.cpp : définit le point d'entrée pour l'application.
//

#include <stdlib.h>
#include <stdio.h>
#include <math.h>
#include <time.h>
#include <SDL.h>

// Variable globale
SDL_Surface* affichage;

void initSDL();
void attendreTouche();
void setPixel(int x, int y, Uint32 coul, int taille = 1);
void actualiser();
void tracerDroite(int x1, int y1, int x2, int y2, int taille = 1, Uint32 couleur = 255);
void tracerCercle(int X, int Y, int r, int taille =1);
void dessinerAiguille(int X, int Y, int r, double h, int m, int s, int taille = 1, Uint32 couleur = 255);
void Horloge();

int main(int argc, char *argv[])
{
	initSDL();
	tracerCercle(160,160,100,3);
	Horloge();
	return EXIT_SUCCESS;
}

//Fonction classique d'initialisation de SDL
void initSDL()
{
	/* Initialisation de la librairie */
	if ( SDL_Init(SDL_INIT_VIDEO) < 0 ) 
	{
		fprintf(stderr, "Erreur SDL : %s\n", SDL_GetError());
		exit(EXIT_FAILURE);
	}
	//Indispensable pour quitter proprement SDL
	atexit(SDL_Quit);
  
	affichage = SDL_SetVideoMode(320,320, 32, SDL_SWSURFACE);

	if(affichage == NULL){
		fprintf(stderr, "Impossible d'activer le mode graphique : %s\n", SDL_GetError());
		exit(EXIT_FAILURE);
	}

	//Nom de la fenetre
	SDL_WM_SetCaption("Horloge", NULL);
}

//Fonction utilisée lors des testes, afin de stoper le programme à un moment précis du code
void attendreTouche()
{
	SDL_Event event;

	do
		SDL_WaitEvent(&event);
		while(event.type != SDL_QUIT && event.type != SDL_KEYDOWN);
}

//Fonction permettant d'afficher un pixel
void setPixel(int x, int y, Uint32 coul, int taille)
{
	if(taille != 1){
		for(int i =-(taille/2) ; i<(taille/2) ; i++)
			for(int j=-(taille/2) ; j<(taille/2) ; j++)
				//Verifie la validite des coordonnees
				if((x+i)>=0 && (y+j)>=0 && (x+i)<affichage->w && (y+j)<affichage->h)

  • ((Uint32*)(affichage->pixels) + (x+i) + (y+j) * affichage->w) = coul;
} else if(x>=0 && y>=0 && x<affichage->w && y<affichage->h)
  • ((Uint32*)(affichage->pixels) + x + y * affichage->w) = coul;
} void actualiser() { SDL_UpdateRect(affichage, 0, 0, 0, 0); } //Fonction permettant de tracer une droite afin de relier deux points void tracerDroite(int x1, int y1, int x2, int y2, int taille, Uint32 couleur) { int x,y; double a,b; if(x2 == x1){ if(y1>y2){ y = y1; y1 = y2; y2 = y; } for(y=y1;y<=y2;y++) setPixel(x1,y,couleur,taille); } else{ //Calcule le coefficient directeur de la droite a = (double)(y2-y1)/(x2-x1); if(a >1 || a < -1){ if(y1>y2){ x = x1; x1 = x2; x2 = x; y = y1; y1 = y2; y2 = y; } //Calcule l'ordonne a l'origine de la droite b = y1-a*x1; for(y=y1;y<=y2;y++){ x = (int)((y - b)/a); setPixel(x,y,couleur,taille); } } else{ if(x1>x2){ x = x1; x1 = x2; x2 = x; y = y1; y1 = y2; y2 = y; } //Calcule l'ordonne a l'origine de la droite b = y1-a*x1; for(x=x1;x<=x2;x++){ y = (int)(a*x + b); setPixel(x,y,couleur,taille); } } } } //Fonction permettant de tracer un cercle à partire de l'origine et du rayon void tracerCercle(int X, int Y, int r, int taille) { double A,t; int x,y; for(x=0;x<=r;x++){ A = (double)(x)/(r); A = acos(A); t = sin(A); y = (int) (t*r); setPixel(x+X,y+Y,SDL_MapRGB(affichage->format,0,0,255),taille); setPixel(x+X,(-y)+Y,SDL_MapRGB(affichage->format,0,0,255),taille); setPixel((-x)+X,y+Y,SDL_MapRGB(affichage->format,0,0,255),taille); setPixel((-x)+X,(-y)+Y,SDL_MapRGB(affichage->format,0,0,255),taille); setPixel(y+X,x+Y,SDL_MapRGB(affichage->format,0,0,255),taille); setPixel(y+X,(-x)+Y,SDL_MapRGB(affichage->format,0,0,255),taille); setPixel((-y)+X,x+Y,SDL_MapRGB(affichage->format,0,0,255),taille); setPixel((-y)+X,(-x)+Y,SDL_MapRGB(affichage->format,0,0,255),taille); } } //Fonction permettant de dessiner les aiguilles de l'horloge en fonction de l'heure void dessinerAiguille(int X, int Y, int r, double h, int m, int s, int taille, Uint32 couleur) { int x,y; double R = r*4/3, A, M_PI = 3.14159265358979323846, M_PI_2 = 1.57079632679489661923; //Calcule coordonnee de l'aiguille des heures puis la dessine A = (M_PI_2)-(h/6)*(M_PI); x = (int)(cos(A)*r + X); y = (int)(-sin(A)*r + Y); tracerDroite(X,Y,x,y,taille,couleur); //Calcule coordonnee de l'aiguille des minutes puis la dessine A = (M_PI_2)-m*(M_PI)/30; x = (int)(cos(A)*R + X); y = (int)(-sin(A)*R + Y); tracerDroite(X,Y,x,y,taille,couleur); //Calcule coordonnee de l'aiguille des secondes puis la dessine A = (M_PI_2)-s*(M_PI)/30; x = (int)(cos(A)*R + X); y = (int)(-sin(A)*R + Y); tracerDroite(X,Y,x,y,1,couleur); } //Fonction principale de notre horloge void Horloge() { long heure; double h; int m,s; SDL_Event event; //Recupere l'heure du systeme time(&heure); heure %= 86400; h = (double)(heure) / (3600) + 1; heure %= 3600; m = heure / 60; heure %= 60; s = heure; do{ dessinerAiguille(160,160,50,h,m,s,2,0);//Efface les aiguilles s++;//Mets a jours l'heure if(s == 60){ m += 1; s = 0; h += 0.01666666666666666; if(h > 12) h = 0; } dessinerAiguille(160,160,50,h,m,s,2,255);//Redessine les aiguilles actualiser(); SDL_Delay(990); SDL_PollEvent(&event); }while(event.type != SDL_QUIT); }

Conclusion :


Bien entendu il s'agit d'un début d'horloge, toute les fonctions de bases sont là. A vous de l'améliorer si le coeur vous en dit.

Codes Sources

A voir également

Ajouter un commentaire Commentaires
Messages postés
232
Date d'inscription
samedi 11 mai 2002
Statut
Membre
Dernière intervention
27 octobre 2007

Pour ceux qui ne connaissent pas, les algorithmes de bresenham permettent de tracer des lignes et des cercles de maniere tres rapide et tres efficace (c'est la meilleure approximation possible).

Pour Snoupy : je regrette, mais l algo de bresenham utilise des variables de decisions pour decider quel est le pixel a allumer, et ce n est pas ce que tu fais, puisque tu calcule directement la valeur de ta fonction. De même pour le cercle, mais un petit point : tu utilises la symetrie du cercle :). Remarque, tu aurais pu aussi utiliser la symetrie de ta ligne ...
Si tu veux implementer les algo de bresenham, mefie toi, la plupart des versions presentes sur le net te donne un algorithme pour le 1er et 2d octant...
voila.

A+
Messages postés
10
Date d'inscription
vendredi 20 février 2004
Statut
Membre
Dernière intervention
11 janvier 2006

J'ai redéfinie moi même les algos, c'est pour ca qu'ils peuvent paraître un peu compliqué. Je ne connaissais pas l'algo de bresenham, mais après avoir regardé sur wikipédia, je dois avoué que le miens est plus long, mais basé sur le même principe.

J'inverse x et y au début selon la valeur du coefficent directeur, puis je trace la fonction y = ax +b.
Messages postés
159
Date d'inscription
lundi 13 juin 2005
Statut
Membre
Dernière intervention
26 février 2009

c'est quoi ces algo PSYCHO ??? je neles connais pas non plus...
Messages postés
232
Date d'inscription
samedi 11 mai 2002
Statut
Membre
Dernière intervention
27 octobre 2007

pfouuuuuu, tu aurais au moins pu utiliser les algos de bresenham pour tes dessins de primitives!!!
Messages postés
159
Date d'inscription
lundi 13 juin 2005
Statut
Membre
Dernière intervention
26 février 2009

wep ce serait bien, pcq là j'ai pas envie de faire un copier-coller et pourtant ce code m'interesse...
Afficher les 7 commentaires

Vous n'êtes pas encore membre ?

inscrivez-vous, c'est gratuit et ça prend moins d'une minute !

Les membres obtiennent plus de réponses que les utilisateurs anonymes.

Le fait d'être membre vous permet d'avoir un suivi détaillé de vos demandes et codes sources.

Le fait d'être membre vous permet d'avoir des options supplémentaires.